【问题标题】:Parsing XML by OpenXML with multiple Parent nodes with multiple child nodes通过具有多个父节点和多个子节点的 OpenXML 解析 XML
【发布时间】:2016-02-18 05:46:19
【问题描述】:

我有以下 XML:

<Report>
    <Accounts>
        <Account>
          <Currency>USD</Currency>
          <AccountBalance>45555</AccountBalance>
          <Payments>
            <PaymentData>
              <PaymentCode>502</PaymentCode>
              <PaymentAmount currCode="GBP">7000.00000000</PaymentAmount>
            </PaymentData>
            <PaymentData>
              <PaymentCode>501</PaymentCode>
              <PaymentAmount currCode="USD">5000.00000000</PaymentAmount>
            </PaymentData>
          </Payments>
        </Account>
        <Account>
          <Currency>USD</Currency>
          <AccountBalance>50000</AccountBalance>
          <Payments>
            <PaymentData>
              <PaymentCode>501</PaymentCode>
              <PaymentAmount currCode="USD">5000.00000000</PaymentAmount>
            </PaymentData>
          </Payments>
        </Account>
    </Accounts>
</Report>

我的 SQL 代码正在使用以下代码对其进行解析:

SELECT  
            [currCode]  AS [Currency], 
            [AccountBalance] AS [AccountBalance],
            [PaymentCode] AS [PaymentCode],
            [PaymentCurrCode] AS [PaymentCurrCode],
            [PaymentAmount] AS [PaymentAmount]
        FROM OPENXML(@hDoc, 'Report/Accounts/Account',2)
            WITH 
            (
                [currCode] [nchar](3) 'currCode',
                [AccountBalance] [decimal](18, 0) 'AccountBalance',

                [PaymentCode] [nchar](10) 'Payments/PaymentData/PaymentCode',
                [PaymentCurrCode] [nchar](3) 'Payments/PaymentData/PaymentAmount/@currCode',
                [PaymentAmount] [decimal](18, 0) 'Payments/PaymentData/PaymentAmount'
            )

我得到以下结果:

currCode | AccountBalance | PaymentCode | PaymentCurrCode | PaymentAmount
————————————————————————————————————————————————————————————————————————————————
USD      | 45555          | 502         |   GBP           |7000.00000000
USD      | 50000          | 501         |   USD           |5000.00000000

我正在尝试使用相同的 openXml 查询获取多个支付数据和多个帐户。如何获取具有以下结果的所有数据:

currCode | AccountBalance | PaymentCode | PaymentCurrCode | PaymentAmount
————————————————————————————————————————————————————————————————————————————————
USD      | 45555          | 502         |   GBP           |7000.00000000
USD      | 45555          | 501         |   USD           |5000.00000000
USD      | 50000          | 501         |   USD           |5000.00000000

【问题讨论】:

  • 嗨,Shuvra,OPENXML 绝对过时了...您是否必须坚持这种方法,或者它也可能是一种更现代的方法?
  • 嗨,Shuvra,没有等到你回答,刚刚发布了两个答案。选择你喜欢的任何东西 :-) (顺便说一句:我投票赞成这个问题,因为它非常清楚:样本数据、自己的方法、错误的输出和预期的输出。如果只是所有这样的问题......谢谢!
  • 嗨Shnugo,很抱歉回复晚了。 OPENXML 有效,但正如您所建议的,我将尝试使用@XML.nodes。再次感谢您的帮助。

标签: sql xml openxml


【解决方案1】:

这是一种使用 XQuery/XPath 方法的最新和最先进的方法。结果是一样的,只是更快更好地阅读:

DECLARE @XML XML=
'<Report>
    <Accounts>
        <Account>
          <Currency>USD</Currency>
          <AccountBalance>45555</AccountBalance>
          <Payments>
            <PaymentData>
              <PaymentCode>502</PaymentCode>
              <PaymentAmount currCode="GBP">7000.00000000</PaymentAmount>
            </PaymentData>
            <PaymentData>
              <PaymentCode>501</PaymentCode>
              <PaymentAmount currCode="USD">5000.00000000</PaymentAmount>
            </PaymentData>
          </Payments>
        </Account>
        <Account>
          <Currency>USD</Currency>
          <AccountBalance>50000</AccountBalance>
          <Payments>
            <PaymentData>
              <PaymentCode>501</PaymentCode>
              <PaymentAmount currCode="USD">5000.00000000</PaymentAmount>
            </PaymentData>
          </Payments>
        </Account>
    </Accounts>
</Report>';

SELECT Payment.value('(../../Currency)[1]','nchar(3)') AS currCode
      ,Payment.value('(../../AccountBalance)[1]','decimal(18,0)') AS AccountBalance
      ,Payment.value('PaymentCode[1]','nchar(10)') AS PaymentCode
      ,Payment.value('PaymentAmount[1]/@currCode','nchar(3)') AS PaymentCurrCode
      ,Payment.value('PaymentAmount[1]','decimal(18,0)') AS PaymentCurrCode
FROM @XML.nodes('Report/Accounts/Account/Payments/PaymentData') AS One(Payment)

【讨论】:

    【解决方案2】:

    这应该适合你:

    DECLARE @XML XML=
    '<Report>
        <Accounts>
            <Account>
              <Currency>USD</Currency>
              <AccountBalance>45555</AccountBalance>
              <Payments>
                <PaymentData>
                  <PaymentCode>502</PaymentCode>
                  <PaymentAmount currCode="GBP">7000.00000000</PaymentAmount>
                </PaymentData>
                <PaymentData>
                  <PaymentCode>501</PaymentCode>
                  <PaymentAmount currCode="USD">5000.00000000</PaymentAmount>
                </PaymentData>
              </Payments>
            </Account>
            <Account>
              <Currency>USD</Currency>
              <AccountBalance>50000</AccountBalance>
              <Payments>
                <PaymentData>
                  <PaymentCode>501</PaymentCode>
                  <PaymentAmount currCode="USD">5000.00000000</PaymentAmount>
                </PaymentData>
              </Payments>
            </Account>
        </Accounts>
    </Report>';
    
    DECLARE @hDoc INT;
    EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML; 
    
    SELECT  
                [currCode]  AS [Currency], 
                [AccountBalance] AS [AccountBalance],
                [PaymentCode] AS [PaymentCode],
                [PaymentCurrCode] AS [PaymentCurrCode],
                [PaymentAmount] AS [PaymentAmount]
            FROM OPENXML(@hDoc, 'Report/Accounts/Account/Payments/PaymentData',2)
                WITH 
                (
                    [currCode] [nchar](3) '../../Currency',
                    [AccountBalance] [decimal](18, 0) '../../AccountBalance',
    
                    [PaymentCode] [nchar](10) 'PaymentCode',
                    [PaymentCurrCode] [nchar](3) 'PaymentAmount/@currCode',
                    [PaymentAmount] [decimal](18, 0) 'PaymentAmount'
                )
    EXEC sp_xml_removedocument @hDoc; 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 2013-08-11
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多