我目前正在使用已使用自定义xml转换器转换为xml的VDA消息类型。但是,源文档中的每个标题和行记录都处于同一级别,如下例所示:
<root>
<row>
<Record_type>512</Record_type>
<Customer_item_Number>A0528406</Customer_item_Number>
<Supplier_item_number>10962915</Supplier_item_number>
</row>
<row>
<Record_type>513</Record_type>
<Date>170306</Date>
<Quantity>115</Quantity>
</row>
<row>
<Record_type>513</Record_type>
<Date>190306</Date>
<Quantity>97</Quantity>
</row>
<row>
<Record_type>512</Record_type>
<Customer_item_Number>A0528433</Customer_item_Number>
<Supplier_item_number>10962916</Supplier_item_number>
</row>
<row>
<Record_type>513</Record_type>
<Date>170306</Date>
<Quantity>115</Quantity>
</row>
<row>
<Record_type>513</Record_type>
<Date>170306</Date>
<Quantity>115</Quantity>
</row>
<row>
<Record_type>513</Record_type>
<Date>170306</Date>
<Quantity>115</Quantity>
</row>
<row>
<Record_type>513</Record_type>
<Date>170306</Date>
<Quantity>115</Quantity>
</row>
</root>
(512)条记录类型是标题,以下(513)条记录类型是其上方的(512)条记录的行。
我正在努力格式化此消息,以便在每个标头(512)记录下方缩进行(513)。
即所需的输出,像这样。
<root>
<Header>
<Record_type>512</Record_type>
<Customer_item_Number>A0528406</Customer_item_Number>
<Supplier_item_number>10962915</Supplier_item_number>
<Line>
<Record_type>513</Record_type>
<Date>170306</Date>
<Quantity>115</Quantity>
</Line>
<Line>
<Record_type>513</Record_type>
<Date>190306</Date>
<Quantity>97</Quantity>
</Line>
</Header>
<Header>
<Record_type>512</Record_type>
<Customer_item_Number>A0528433</Customer_item_Number>
<Supplier_item_number>10962916</Supplier_item_number>
<Line>
<Record_type>513</Record_type>
<Date>170306</Date>
<Quantity>115</Quantity>
</Line>
<Line>
<Record_type>513</Record_type>
<Date>170306</Date>
<Quantity>115</Quantity>
</Line>
<Line>
<Record_type>513</Record_type>
<Date>170306</Date>
<Quantity>115</Quantity>
</Line>
<Line>
<Record_type>513</Record_type>
<Date>170306</Date>
<Quantity>115</Quantity>
</Line>
</Header>
</root>
我使用以下兄弟姐妹取得了一些成功,但是我无法将其与先前的兄弟姐妹联系起来,仅在下一个循环之前过滤掉所需的记录。
我希望有人能够提供帮助。 :)
答案 0 :(得分:1)
在XQuery 3.1中,您可以使用翻滚窗口https://www.w3.org/TR/xquery-31/#id-tumbling-windows:
<root>
{
for tumbling window $record in root/row
start $s when $s/Record_type = 512
return
<Header>
{
head($record)/*,
tail($record) !
<Line>
{ * }
</Line>
}
</Header>
}
</root>
答案 1 :(得分:1)
如果您的XQuery处理器支持 XQuery 3.0 的window
clauses,则您的查询(至少在概念上)非常简单有效:
foreach ($xml->xpath('//ReturnValues') as $item) {
否则,您必须使用<root>{
for tumbling window $w in /root/row
start when true()
end next $n when $n/Record_type = '512'
return <Header>{
head($w)/*,
for $line in tail($w)
return <Line>{$line/*}</Line>
}</Header>
}</root>
和preceding-sibling
XPath轴,就像Mads Hansen在他的回答中所示:
following-sibling
在这里,我们首先获取当前标头之后的所有行,然后检查每一行是否在它之前的最后一个标头是当前行。在这里重要的是使用<root>{
for $header in /root/row[Record_type = '512']
return <Header>{
$header/*,
for $line in $header/following-sibling::row[Record_type = '513']
let $prev-headers := $line/preceding-sibling::row[Record_type = '512']
where $prev-headers[last()] is $header
return <Line>{$line/*}</Line>
}</Header>
}</root>
而不是is
或=
,因为后两者仅在原子项上起作用。这意味着在执行比较之前,XML节点已被原子化(即被精简为仅其连接的文本内容)。 eq
运算符会比较节点身份。
答案 2 :(得分:0)
对于每个row
为Record_type
的{{1}},创建一个512
元素。
为了找到相关的Header
组元素的row
个元素,您想从512位{{ 1}},谁是第一个Line
是当前标题。
row