2015-07-09 76 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是完美的答案和它来的速度! –

相关问题