2015-07-09 57 views
1

我對於SQL Server和存儲過程開始非常陌生。我需要能夠解析傳入的XML文件以獲取特定元素的值,並在稍後的過程中比較/保存它。SQL Server從XML參數中獲取值以用於以後的查詢

我有幾件東西堆積在我身上。我需要的一個元素深深地埋藏在文檔中。我沒有運氣通過名稱使用類似的方法搜索它:

select CurrentBOD = c.value('(local-name(.))[1]', 'VARCHAR(MAX)'), 
       c.value('(.)[1]', 'VARCHAR(MAX)') from @xml.nodes('PutMessage/payload/content/AcknowledgePartsOrder/ApplicationArea/BODId') as BODtable(c) 

它總是返回null。

所以,我想類似這樣:

declare @BODtable TABLE(FieldName VARCHAR(MAX), 
        FieldValue VARCHAR(MAX)) 
    SELECT 
    FieldName = nodes.value('local-name(.)', 'varchar(50)'), 
    FieldValue = nodes.value('(.)[1]', 'varchar(50)') 
    FROM 
    @xml.nodes('//*') AS BODtable(nodes) 

    declare @CurrentBOD VARCHAR(36) 
    set @CurrentBOD = '' 

    SET @CurrentBOD = (SELECT FieldValue from @BODtable WHERE FieldName = 'BODId') 

這爲我提供了節點名稱和值的列表中正確(我在查詢中測試這一點,並BODtable有正確的價值觀中列出的所有元素) ,但是當我設置@CurrentBOD時,它變爲空。

我錯過了一個更簡單的方法來做到這一點?我以某種方式搞砸了這兩種方法?

這裏是我的解析,以供參考XML的一部分:

<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"   xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"  xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-  secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-  wss-wssecurity-utility-1.0.xsd"> 
     <soap:Header> 
<payloadManifest xmlns="???"> 
    <c contentID="Content0" namespaceURI="???" element="AcknowledgePartsOrder" version="4.0" /> 
</payloadManifest> 
<wsa:Action>http://www.starstandards.org/webservices/2005/10/transport/operations/PutMessage</wsa:Action> 
<wsa:MessageID>uuid:df8c66af-f364-4b8f-81d8-06150da14428</wsa:MessageID> 
<wsa:ReplyTo> 
    <wsa:Address>http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:Address> 
</wsa:ReplyTo> 
<wsa:To>???</wsa:To> 
<wsse:Security soap:mustUnderstand="1"> 
    <wsu:Timestamp wsu:Id="Timestamp-bd91e76f-c212-4555-9b23-f66f839672bd"> 
    <wsu:Created>2013-01-03T21:52:48Z</wsu:Created> 
    <wsu:Expires>2013-01-03T21:53:48Z</wsu:Expires> 
    </wsu:Timestamp> 
    <wsse:UsernameToken xmlns:wsu="???" wsu:Id="???"> 
    <wsse:Username>???</wsse:Username> 
    <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">???</wsse:Password> 
    <wsse:Nonce>???</wsse:Nonce> 
    <wsu:Created>2013-01-03T21:52:48Z</wsu:Created> 
    </wsse:UsernameToken> 
</wsse:Security> 
    </soap:Header> 
    <soap:Body> 
<PutMessage xmlns="??????"> 
    <payload> 
    <content id="???"> 
     <AcknowledgePartsOrder xmlns="???" xmlns:xsi="???" xsi:schemaLocation="??? ???" revision="???" release="???" environment="???n" lang="en-US" bodVersion="???"> 
     <ApplicationArea> 
      <Sender> 
      <Component>???</Component> 
      <Task>???</Task> 
      <ReferenceId>???</ReferenceId> 
      <CreatorNameCode>???</CreatorNameCode> 
      <SenderNameCode>???</SenderNameCode> 
      <DealerNumber>???</DealerNumber> 
      <PartyId>???</PartyId> 
      <LocationId /> 
      <ServiceId /> 
      </Sender> 
      <CreationDateTime>2013-01-03T21:52:47</CreationDateTime> 
      <BODId>71498800-c098-4885-9ddc-f58aae0e5e1a</BODId> 
      <Destination> 
      <DestinationNameCode>???</DestinationNameCode> 

回答

1

您需要尊重的XML命名空間!

首先,你的目標XML節點<BODId><soap:Envelope><soap:Body>標籤 - 都需要包含在您的選擇。

其次,無論是<PutMessage>還有​​節點似乎有默認XML命名空間(那些xmlns=....沒有前綴) - 當您使用XPath選擇數據的必須得到尊重

所以假設<PutMessage xmlns="urn:pm"><AcknowledgePartsOrder xmlns="urn:apo">(這些都只是猜測對我而言 - 與您還沒有表現出在這裏使用實際 XML命名空間替換),你應該能夠使用XPath來得到了什麼你正在尋找:

;WITH XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS soap, 
        'urn:pm' AS ns, 'urn:apo' AS apo) 
SELECT 
    XC.value('(apo:BODId)[1]', 'varchar(100)') 
FROM 
    @YourXmlVariable.nodes('/soap:Envelope/soap:Body/ns:PutMessage/ns:payload/ns:content/apo:AcknowledgePartsOrder/apo:ApplicationArea') AS XT(XC) 

這並不在我的情況恢復的預期值(71498800-c098-4885-9ddc-f58aae0e5e1a)。

+0

非常感謝Marc!我很熟悉命名空間,但我不知何故錯過了你可以像這樣在MSSQL中使用管理器 - 我只是假設命名空間沒有考慮到。我在經理和BINGO中正確定義了我的名稱空間。再次感謝! –

+1

如果你對這個答案感到滿意,Marc肯定會讚賞你的投票和/或接受答案。 – Shnugo

+1

我在這裏有一個新的帳戶,所以它不會讓我upvote。無論如何+1是完美的答案和它來的速度! –

相關問題