导航多个节点 Xquery xml SQL Server 2019

Navigate multiple nodes Xquery xml SQL Server 2019

嗨,我有当前 XML:

<?xml version="1.0" encoding="utf-8"?>
<tcpos-export>
  <transactions>
    <transaction>
        <code>1</code>
        <description>MAXI MERCADO SELECTO</description>
      </shop>

        <code>2</code>
        <description>MAÑANITA PANADERIA</description>
      </till>
      <cashier>
        <code>2004</code>
        <description>NELSON PANADERIA</description>
        <first-name>NELSON PANADERIA</first-name>
      </cashier>

      <trans-item type="article">
        <hash-code>832129</hash-code>
        <code>30237</code>
        <quantity>1</quantity>
        <unit-price>0.50</unit-price>
        <total-price>0.50</total-price>
     
      </trans-item>
      <payment type="cash">
        <code>01</code>
        <description>Efectivo</description>
        <description-translations />
        <amount>0.50</amount>
        <prepayment>false</prepayment>
        <signature-required>false</signature-required>
        <payment-timestamp>18.08.2021 06:51:27</payment-timestamp>
        <cash-change>4.50</cash-change>
        <cash-given>5.00</cash-given>
      </payment>

用这个 xquery sql 2019:

--procesar articulos del dia de venta
SELECT 
        trans.value('(shop/description/text())[1]','varchar(100)') tienda,
        trans.value('(till/code/text())[1]','varchar(100)') caja,
        trans.value('(cashier/code/text())[1]','varchar(100)') cajero,
        trans.value('(beginning-timestamp/text())[1]','varchar(100)') fecha,
        trans.value('(trans-num/text())[1]','varchar(100)') transaccion,
        item.value('(code/text())[1]','varchar(100)') itemcode,
        item.value('(description/text())[1]','varchar(100)') description,
     
        item.value('(hash-code/text())[1]','int') hashcode

FROM [dbo].[XmlImport] xi

CROSS APPLY xi.[LoadedXML].nodes('tcpos-export/transactions/transaction') x1(trans)

CROSS APPLY x1.trans.nodes('trans-item[
    hash-code/text() and
    not( unit-price[contains(text()[1], "-")] ) and
    not( taxable-amount[contains(text()[1], "-")] ) and
    not( delete-operator-id/text() )
]') x2(item)

CROSS APPLY (VALUES (
    item.value('(quantity/text())[1]','numeric(10,3)'),
    item.value('(weight/text())[1]','numeric(10,3)'),
    item.value('(vat-code/text())[1]','varchar(100)')
) ) v(quantity, weight, vatcode)

ORDER BY hashcode;

我已经从交易节点示例收银台正确获取这些列,直到。另外我从 节点获取信息。但是,我对如何从下一个节点获取信息感到困惑

<payment type="cash">
        <code>01</code>
        <description>Efectivo</description>
        <description-translations />

我想获取代码和描述

我尝试了以下方法:

将其添加为额外的交叉应用

CROSS APPLY xi.[LoadedXML].nodes('tcpos-export/transactions/transaction') x3(payments)

CROSS APPLY x3.payments.nodes('payment[
    code/text() 
]') x4(payment)

并在 select 最后:

payment.value('(code/text())[1]','varchar(100)')

但是当我 运行 查询时,它保持 运行ning 和 运行ning,并被冻结。我不知道我还能做什么。

请给我一些提示。

谢谢

您有两个选择:

  • 您可以直接在 select
  • 中 select 值
SELECT 
        trans.value('(shop/description/text())[1]','varchar(100)') tienda,
        trans.value('(payment/amount/text())[1]','numeric(18,2)') caja,
        -- etc....

FROM [dbo].[XmlImport] xi
-- etc....
  • 或者,您可以再做一个 CROSS APPLY nodes。这就是您想要做的,但它应该是 x1.trans.nodes('payment'),因为您想要从 transaction 而不是根 XML.[= 中拆分每个 Payment 节点30=]

Note that the VALUES clause I added in was needed only because we needed to refer multiple times to the same node.

SELECT 
        trans.value('(shop/description/text())[1]','varchar(100)') tienda,
        trans.value('(till/code/text())[1]','varchar(100)') caja,
        trans.value('(cashier/code/text())[1]','varchar(100)') cajero,
        trans.value('(beginning-timestamp/text())[1]','varchar(100)') fecha,
        trans.value('(trans-num/text())[1]','varchar(100)') transaccion,
        item.value('(code/text())[1]','varchar(100)') itemcode,
        item.value('(description/text())[1]','varchar(100)') description,
     
        item.value('(hash-code/text())[1]','int') hashcode
        payment.value('(code/text())[1]','int') paymentCode
FROM [dbo].[XmlImport] xi

CROSS APPLY xi.[LoadedXML].nodes('tcpos-export/transactions/transaction') x1(trans)

CROSS APPLY x1.trans.nodes('trans-item[
    hash-code/text() and
    not( unit-price[contains(text()[1], "-")] ) and
    not( taxable-amount[contains(text()[1], "-")] ) and
    not( delete-operator-id/text() )
]') x2(item)

CROSS APPLY x1.trans.nodes('payment') x3(payment)

ORDER BY hashcode;

请注意,如果可能没有 payment 节点,那么您需要 OUTER APPLY 而不是 CROSS APPLY