2016-01-18 141 views
1

我想從SOAP API解析一些XML。我對XML非常陌生,但是隻有聲明的主體才能使用它。我試過應用一些簡單的命名空間,但我不確定這是否是正確的追求路徑。如何應用XML名稱空間

DECLARE @XmlFile XML = 
'<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <soap:Body> 
     <Account_GetDataArrayResponse xmlns="http://e-conomic.com"> 
      <Account_GetDataArrayResult> 
       <AccountData> 
        <Handle> 
         <Number>1000</Number> 
        </Handle> 
        <Number>1000</Number> 
        <Name>RESULTATOPGØRELSE</Name> 
        <Type>Heading</Type> 
        <DebitCredit>Debit</DebitCredit> 
        <IsAccessible>true</IsAccessible> 
        <BlockDirectEntries>false</BlockDirectEntries> 
        <Balance>0.00</Balance> 
       </AccountData> 
       <AccountData> 
        <Handle> 
         <Number>1001</Number> 
        </Handle> 
        <Number>1001</Number> 
        <Name>Omsætning</Name> 
        <Type>Heading</Type> 
        <DebitCredit>Debit</DebitCredit> 
        <IsAccessible>true</IsAccessible> 
        <BlockDirectEntries>false</BlockDirectEntries> 
        <Balance>0.00</Balance> 
       </AccountData> 
      </Account_GetDataArrayResult> 
     </Account_GetDataArrayResponse> 
    </soap:Body> 
</soap:Envelope>' 

;WITH XMLNAMESPACES('http://www.w3.org/2001/XMLSchema' AS e) 


SELECT 
    AccountHandleNumber = AccountData.value('(Handle/Number)[1]', 'int') 
    ,AccountName = AccountData.value('(Name)[1]', 'varchar(20)') 
    ,AccountNumber = AccountData.value('(Number)[1]', 'int') 
    ,AccountType = AccountData.value('(Type)[1]','varchar(20)') 
    ,AccountDebitCredit = AccountData.value('(DebitCredit)[1]', 'varchar(20)') 
    ,AccountIsAccessible = AccountData.value('(IsAccessible)[1]', 'varchar(20)') 
    ,AccountBlockDirectEntries = AccountData.value('(BlockDirectEntries)[1]', 'varchar(20)') 
    ,AccountBalance = AccountData.value('(Balance)[1]', 'float') 
FROM @XMLFile.nodes('/Account_GetDataArrayResponse/Account_GetDataArrayResult/AccountData') AS XTbl(AccountData) 

回答

1

沒錯,這就是非常正道!

但是,你不讀你擁有整個XML - 你必須真正開始根節點 - 所以儘量去適應你的代碼是這樣的:

;WITH XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS e, 
        DEFAULT 'http://e-conomic.com') 
SELECT 
    AccountHandleNumber = AccountData.value('(Handle/Number)[1]', 'int') 
    ..... 
FROM 
    @XMLFile.nodes('/e:Envelope/e:Body/Account_GetDataArrayResponse/Account_GetDataArrayResult/AccountData') AS XTbl(AccountData) 

首先的 - 你需要還要處理文檔一開始的<soap:Envelope><soap:Body>標籤 - 您已爲此創建了一個XML名稱空間別名e - 因此您需要在.nodes()調用中的XPath表達式開頭處包含/e:Envelope/e:Body

另外:<Account_GetDataArrayResponse>節點聲明它獲取整個XML文檔的其餘部分用於另一個XML命名空間 - 我補充說,由於DEFAULT XML命名空間來查詢,所以它會在XPath表達式可以應用於任何節點沒有一個明確的XML命名空間前綴關聯它

+0

非常感謝,這爲我解決了不少問題。 不過,似乎有東西不能正常工作,因爲我沒有得到任何記錄返回。查詢執行但不返回任何內容。我使用正確的命名空間,有三個,但我想我要使用xmlns:? 任何幫助表示讚賞。 Rasmus –

+0

@RasmusRødbyKristiansen:是的 - 您在'WITH XMLNAMESPACES ....'標題中使用*錯誤* XML名稱空間;您需要使用與原始XML文檔中的「soap」前綴關聯的那個。嘗試我的更新回覆 –

+0

太好了,謝謝你! 我當然需要閱讀所有這些,因爲我看到它的工作,但並不真正理解爲什麼。有一個美好的一天.. @marc_s –