【问题标题】:Extract value from XML not working with querying nodes or value从 XML 中提取值不适用于查询节点或值
【发布时间】:2021-04-07 00:03:25
【问题描述】:

我正在使用 SQL Server 2016,我正在尝试从下面的 XML 中提取 <Org>Insurance Technologies Corporation</Org> 值。

我已尝试在我的 tsql 代码中使用 nodes 和 value 查询该值,但无济于事,因为我不断获得 Rater 列的 NULL 值。

我不确定在这两种情况下我做错了什么。任何帮助/方向将不胜感激。谢谢。

这是我的 XML:

<ACORD xmlns="http://www.ACORD.org/standards/PC_Surety/ACORD1.11.0/xml/" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <SignonRq>
    <SignonTransport>
      <SignonRoleCd>Agent</SignonRoleCd>
      <CustId>
        <SPName>turborater.com</SPName>
        <CustLoginId>99999</CustLoginId>
      </CustId>
    </SignonTransport>
    <ClientDt>2019-07-05T11:05:36</ClientDt>
    <CustLangPref>EN-US</CustLangPref>
    <ClientApp>
      <Org>Insurance Technologies Corporation</Org>
      <Name>ITC.Insurance.EmpowerAnnSvngsRR.TX</Name>
      <Version>1.0.0.0</Version>
    </ClientApp>
  </SignonRq>
 </ACORD>

这是我使用节点的 tsql 代码:

SELECT * 
FROM (
    SELECT rtr.BridgedDate, rtr.RealTimeRequestSysId, rtr.QuoteId, rtr.AgentId, rtr.XmlRequest
        , x.m.value('(Org)[1]', 'varchar(max)') as Rater
    FROM dbo.AUT_RealTimeRequest rtr
        OUTER APPLY rtr.XmlRequest.nodes('ACORD/SignonRq/ClientApp') x(m)
    WHERE rtr.BridgedDate BETWEEN '2020-11-01 00:00:00.000' AND '2020-11-30 23:59:59.997'
) y
WHERE y.AgentId = 3
AND y.QuoteId IS NOT NULL
ORDER BY y.QuoteId asc, y.BridgedDate asc;

这是我使用值的 tsql 代码:

SELECT rtr.BridgedDate, rtr.XMLRequest, 
rtr.XMLRequest.value('(/ACORD/SignonRq/ClientApp/Org)[1]','varchar(max)') as RaterValue
FROM dbo.AUT_RealTimeRequest rtr
WHERE rtr.QuoteId IS NOT NULL
AND rtr.AgentId = 3 --21001
AND rtr.BridgedDate BETWEEN '2020-11-01 00:00:00.000' AND '2020-11-30 23:59:59.997'
ORDER BY rtr.QuoteId asc, rtr.BridgedDate asc;

【问题讨论】:

    标签: sql sql-server xml tsql sql-server-2016


    【解决方案1】:

    您可以尝试使用WITH XMLNAMESPACES 来处理命名空间:

    declare @xml xml='<ACORD xmlns="http://www.ACORD.org/standards/PC_Surety/ACORD1.11.0/xml/" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <SignonRq>
        <SignonTransport>
          <SignonRoleCd>Agent</SignonRoleCd>
          <CustId>
            <SPName>turborater.com</SPName>
            <CustLoginId>99999</CustLoginId>
          </CustId>
        </SignonTransport>
        <ClientDt>2019-07-05T11:05:36</ClientDt>
        <CustLangPref>EN-US</CustLangPref>
        <ClientApp>
          <Org>Insurance Technologies Corporation</Org>
          <Name>ITC.Insurance.EmpowerAnnSvngsRR.TX</Name>
          <Version>1.0.0.0</Version>
        </ClientApp>
      </SignonRq>
     </ACORD>'
    
    ; WITH XMLNAMESPACES (DEFAULT 'http://www.ACORD.org/standards/PC_Surety/ACORD1.11.0/xml/') 
    SELECT 
         l.value (
        'Org[1]'
        ,'varchar(100)' ) Org
        FROM @xml.nodes('//SignonRq') r(n) CROSS APPLY r.n.nodes('ClientApp') lines(l)
    

    结果:

    【讨论】:

      【解决方案2】:

      您正在忽略 XML 数据中存在的 XML 命名空间:

      <ACORD xmlns="http://www.ACORD.org/standards/PC_Surety/ACORD1.11.0/xml/" 
             *****************************************************************
             This is the "default" XML namespace for this XML data
      

      试试这个:

      WITH XMLNAMESPACES(DEFAULT 'http://www.ACORD.org/standards/PC_Surety/ACORD1.11.0/xml/')
          SELECT 
              rtr.BridgedDate, rtr.XMLRequest, 
              rtr.XMLRequest.value('(/ACORD/SignonRq/ClientApp/Org)[1]', 'VARCHAR(50)') AS RaterValue
          FROM 
              dbo.AUT_RealTimeRequest rtr
          WHERE 
              rtr.QuoteId IS NOT NULL
              AND rtr.AgentId = 3 --21001
              AND rtr.BridgedDate BETWEEN '2020-11-01 00:00:00.000' AND '2020-11-30 23:59:59.997'
          ORDER BY 
              rtr.QuoteId ASC, rtr.BridgedDate ASC;
      

      【讨论】:

      • 感谢您的帮助和时间回复。效果很好!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-10
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 2014-08-06
      • 2019-04-27
      • 1970-01-01
      相关资源
      最近更新 更多