从每个标签的下一个节点检索关联值
Retrieve associated value from next node for each tag
我有以下 XML:
<Envelope format="ProceedoOrderTransaction2.1">
<Sender>SENDER</Sender>
<Receiver>RECEIVER</Receiver>
<EnvelopeID>xxxxx</EnvelopeID>
<Date>2021-05-06</Date>
<Time>11:59:46</Time>
<NumberOfOrder>1</NumberOfOrder>
<Order>
<Header>
<OrderNumber>POXXXXX</OrderNumber>
</Header>
<Lines>
<Line>
<LineNumber>1</LineNumber>
<ItemName>Ipsum Lorum</ItemName>
<SupplierArticleNumber>999999</SupplierArticleNumber>
<UnitPrice vatRate="25.0">50</UnitPrice>
<UnitPriceBasis>1</UnitPriceBasis>
<OrderedQuantity unit="Styck">200</OrderedQuantity>
<AdditionalItemProperty Key="ARTIKELNUMMER" Description="Unik ordermärkning (artikelnummer):" />
<Value>999999</Value>
<AdditionalItemProperty Key="BESKRIVNING" Description="Kort beskrivning:" />
<Value>Ipsum Lorum</Value>
<AdditionalItemProperty Key="BSKRIVNING" Description="Beskrivning:" />
<Value>Ipsum Lorum</Value>
<AdditionalItemProperty Key="ENHET" Description="Enhet:" />
<Value>Styck</Value>
<AdditionalItemProperty Key="KVANTITET" Description="Kvantitet:" />
<Value>200</Value>
<AdditionalItemProperty Key="PRIS" Description="Pris/Enhet (ex. moms):" />
<Value>50</Value>
<AdditionalItemProperty Key="VALUTA" Description="Valuta:" />
<Value>SEK</Value>
<Accounting>
<AccountingLine amount="10000">
<AccountingValue dimensionPosition="001" dimensionExternalID="ACCOUNT">xxx</AccountingValue>
<AccountingValue dimensionPosition="002" dimensionExternalID="F1">Ipsum Lorum</AccountingValue>
<AccountingValue dimensionPosition="005" dimensionExternalID="F3">1</AccountingValue>
<AccountingValue dimensionPosition="010" dimensionExternalID="F2">9999</AccountingValue>
</AccountingLine>
</Accounting>
</Line>
</Lines>
</Order>
</Envelope>
我能够正确地将所有值解析为 table 结构,但 1 个值除外,以确保它与其标签相关联的方式。所以我绊倒的地方是我正确地得到每个 AdditionalItemProperty
1 行并且我能够得到 Key
和 Description
标签值,例如 BESKRIVNING
和 Kort beskrivning:
,但我无法(以合理的方式)获取 <Value> </Value>
括号之间的值,该值也与每个标签值相关联。因此,对于标签键值 BESKRIVNING
,关联值是 99999,它似乎与它关联的 AdditionalItemProperty
处于同一层次结构级别(我知道这很疯狂)。似乎他们使用的逻辑是 AdditionalItemProperty
的值将遵循 AdditionalItemProperty
标签。
我正在使用 SQL Server 2019。我已经走到这一步了:
-- Purchaseorderrowattributes
select top(10)
i.value(N'(./Header/OrderNumber/text())[1]', 'nvarchar(30)') as OrderNumber,
ap.value(N'(../LineNumber/text())[1]', 'nvarchar(30)') as LineNumber,
ap.value(N'(@Description)', 'nvarchar(50)') property_description
from
load.proceedo_orders t
outer apply
t.xml_data.nodes('Envelope/Order') AS i(i)
outer apply
i.nodes('Lines/Line/AdditionalItemProperty') as ap(ap)
where
file_name = @filename
产生以下输出:
OrderNumber LineNumber property_description
--------------------------------------------
PO170006416 1 Antal timmar
PO170006416 1 Beskrivning
PO170006416 1 Kompetensområde
PO170006416 1 Roll
PO170006416 1 Ordernummer
PO170006416 1 Timpris
我找不到以正确方式为每个 属性 添加值的方法。由于值的排序将始终与 AdditionalItemProperty 的排序相同,我找到了获得 AdditionalItemProperty 排序的解决方案,然后我可以使用 rownumber,然后我希望将 rownumber 值输入到
中的括号中
ap.value(N'(../Value/text())[1]', 'nvarchar(50)') property_description
但是 SQL 服务器抛出异常,它必须是字符串文字。
所以要清楚我尝试用类似的东西做什么:
ap.value(CONCAT( N'(../Value/text())[', CAST(ROWNUMBER as varchar) ,']'), 'nvarchar(50)') property_description
SQL 服务器使用 XQuery 1.0.
您可以使用 >>
节点比较运算符来查找 Value
兄弟节点,代码类似于以下内容:
-- Purchaseorderrowattributes
select top(10)
i.value(N'(./Header/OrderNumber/text())[1]', 'nvarchar(30)') as OrderNumber
,ap.value(N'(../LineNumber/text())[1]', 'nvarchar(30)') as LineNumber
,ap.value(N'(@Description)', 'nvarchar(50)') property_description
,ap.query('
let $property := .
return (../Value[. >> $property][1])/text()
').value('.[1]', 'varchar(20)') as property_value
from load.proceedo_orders t
outer apply t.xml_data.nodes('Envelope/Order') AS i(i)
outer apply i.nodes('Lines/Line/AdditionalItemProperty') as ap(ap)
where file_name = @filename
这是怎么回事?
let $property := .
正在创建对当前 AdditionalItemProperty
节点的引用。
../Value[. >> $property]
升序到父节点,Line
,然后再次降序找到 AditionalItemProperty
节点引用之后的 Value
节点,其中 [1]
选择这些节点中的第一个。
有关更多详细信息,请参阅 3.5.3 Node Comparisons 部分。
我有以下 XML:
<Envelope format="ProceedoOrderTransaction2.1">
<Sender>SENDER</Sender>
<Receiver>RECEIVER</Receiver>
<EnvelopeID>xxxxx</EnvelopeID>
<Date>2021-05-06</Date>
<Time>11:59:46</Time>
<NumberOfOrder>1</NumberOfOrder>
<Order>
<Header>
<OrderNumber>POXXXXX</OrderNumber>
</Header>
<Lines>
<Line>
<LineNumber>1</LineNumber>
<ItemName>Ipsum Lorum</ItemName>
<SupplierArticleNumber>999999</SupplierArticleNumber>
<UnitPrice vatRate="25.0">50</UnitPrice>
<UnitPriceBasis>1</UnitPriceBasis>
<OrderedQuantity unit="Styck">200</OrderedQuantity>
<AdditionalItemProperty Key="ARTIKELNUMMER" Description="Unik ordermärkning (artikelnummer):" />
<Value>999999</Value>
<AdditionalItemProperty Key="BESKRIVNING" Description="Kort beskrivning:" />
<Value>Ipsum Lorum</Value>
<AdditionalItemProperty Key="BSKRIVNING" Description="Beskrivning:" />
<Value>Ipsum Lorum</Value>
<AdditionalItemProperty Key="ENHET" Description="Enhet:" />
<Value>Styck</Value>
<AdditionalItemProperty Key="KVANTITET" Description="Kvantitet:" />
<Value>200</Value>
<AdditionalItemProperty Key="PRIS" Description="Pris/Enhet (ex. moms):" />
<Value>50</Value>
<AdditionalItemProperty Key="VALUTA" Description="Valuta:" />
<Value>SEK</Value>
<Accounting>
<AccountingLine amount="10000">
<AccountingValue dimensionPosition="001" dimensionExternalID="ACCOUNT">xxx</AccountingValue>
<AccountingValue dimensionPosition="002" dimensionExternalID="F1">Ipsum Lorum</AccountingValue>
<AccountingValue dimensionPosition="005" dimensionExternalID="F3">1</AccountingValue>
<AccountingValue dimensionPosition="010" dimensionExternalID="F2">9999</AccountingValue>
</AccountingLine>
</Accounting>
</Line>
</Lines>
</Order>
</Envelope>
我能够正确地将所有值解析为 table 结构,但 1 个值除外,以确保它与其标签相关联的方式。所以我绊倒的地方是我正确地得到每个 AdditionalItemProperty
1 行并且我能够得到 Key
和 Description
标签值,例如 BESKRIVNING
和 Kort beskrivning:
,但我无法(以合理的方式)获取 <Value> </Value>
括号之间的值,该值也与每个标签值相关联。因此,对于标签键值 BESKRIVNING
,关联值是 99999,它似乎与它关联的 AdditionalItemProperty
处于同一层次结构级别(我知道这很疯狂)。似乎他们使用的逻辑是 AdditionalItemProperty
的值将遵循 AdditionalItemProperty
标签。
我正在使用 SQL Server 2019。我已经走到这一步了:
-- Purchaseorderrowattributes
select top(10)
i.value(N'(./Header/OrderNumber/text())[1]', 'nvarchar(30)') as OrderNumber,
ap.value(N'(../LineNumber/text())[1]', 'nvarchar(30)') as LineNumber,
ap.value(N'(@Description)', 'nvarchar(50)') property_description
from
load.proceedo_orders t
outer apply
t.xml_data.nodes('Envelope/Order') AS i(i)
outer apply
i.nodes('Lines/Line/AdditionalItemProperty') as ap(ap)
where
file_name = @filename
产生以下输出:
OrderNumber LineNumber property_description
--------------------------------------------
PO170006416 1 Antal timmar
PO170006416 1 Beskrivning
PO170006416 1 Kompetensområde
PO170006416 1 Roll
PO170006416 1 Ordernummer
PO170006416 1 Timpris
我找不到以正确方式为每个 属性 添加值的方法。由于值的排序将始终与 AdditionalItemProperty 的排序相同,我找到了获得 AdditionalItemProperty 排序的解决方案,然后我可以使用 rownumber,然后我希望将 rownumber 值输入到
中的括号中ap.value(N'(../Value/text())[1]', 'nvarchar(50)') property_description
但是 SQL 服务器抛出异常,它必须是字符串文字。
所以要清楚我尝试用类似的东西做什么:
ap.value(CONCAT( N'(../Value/text())[', CAST(ROWNUMBER as varchar) ,']'), 'nvarchar(50)') property_description
SQL 服务器使用 XQuery 1.0.
您可以使用 >>
节点比较运算符来查找 Value
兄弟节点,代码类似于以下内容:
-- Purchaseorderrowattributes
select top(10)
i.value(N'(./Header/OrderNumber/text())[1]', 'nvarchar(30)') as OrderNumber
,ap.value(N'(../LineNumber/text())[1]', 'nvarchar(30)') as LineNumber
,ap.value(N'(@Description)', 'nvarchar(50)') property_description
,ap.query('
let $property := .
return (../Value[. >> $property][1])/text()
').value('.[1]', 'varchar(20)') as property_value
from load.proceedo_orders t
outer apply t.xml_data.nodes('Envelope/Order') AS i(i)
outer apply i.nodes('Lines/Line/AdditionalItemProperty') as ap(ap)
where file_name = @filename
这是怎么回事?
let $property := .
正在创建对当前AdditionalItemProperty
节点的引用。../Value[. >> $property]
升序到父节点,Line
,然后再次降序找到AditionalItemProperty
节点引用之后的Value
节点,其中[1]
选择这些节点中的第一个。
有关更多详细信息,请参阅 3.5.3 Node Comparisons 部分。