我正在尝试向XQuery中与其位置对应的标记添加属性,但仅涉及相同标记名称的兄弟。具体来说,列表中的项目。所以这里有2个潜在的查询输出:
<list>
<title>foo</title>
<item>bar1</item>
<item>bar2</item>
</list>
<list>
<item>bar1</item>
<item>bar2</item>
</list>
对于两者,这是添加属性时所需的结果:
<list>
<title>foo</title>
<item position="1">bar1</item>
<item position="2">bar2</item>
</list>
<list>
<item position="1">bar1</item>
<item position="2">bar2</item>
</list>
我正在使用的当前查询是:
count($item/preceding-sibling::*)+1
但是,计数包括每个标记,而不仅仅是item
个标记。所以在上面带有title标签的例子中,它会计算,所以我得到:
<list>
<title>foo</title>
<item position="2">bar1</item>
<item position="3">bar2</item>
</list>
我尝试了一些方法,例如减去列表中没有item
标记名称的所有子项的计数,例如:
count($item/preceding-sibling::*)+1-count($list/*[local-name() != 'item'])
和其他一些类似的方法但无济于事。我怎样才能做到这一点?
编辑:
以下是我如何做的背景示例。输入数据:
<LIST1>
<TITLE>REASON FOR REVISION</TITLE>
<L1ITEM KEY="L1I10254244923043">
<PARA>Summary - Background: Updated and added related references.</PARA>
</L1ITEM>
<L1ITEM KEY="L1I20300231297755">
<PARA>Summary - Action: Updated to add more work and new groups and configurations.</PARA>
</L1ITEM>
</LIST1>
然后我将LIST1根元素传递给这个函数:
declare function local:listx($listx as element()){
<list level="{substring(name($listx),5)}">
{
for $lxitem in $listx/*
return if (name($lxitem) = "TITLE") then (
<title>{local:concatText($lxitem)}</title>
)
else local:extract($lxitem, "item", [
["position", count($lxitem/preceding-sibling::*)+1]
])
}
</list>
};
concatText
函数只是将所有文本与空格分隔符连接在一起,没有问题。 extract()
功能如下:
declare function local:extract(
$root as element(), $tag as xs:string, $props as array(*)
) {
element {$tag}{
for $prop at $i in $props
where array:size($prop) != 0
return attribute {$props($i)(1)} {$prop($i)(2)},
for $child in $root/*
return switch(name($child))
case "TXTGRPHC" return local:plaintext($child)
case "PARA" return local:plaintext($child)
case ...
default return ()
}
};
作为旁注,我在这里添加属性的方式,整个2D数组$props
,只会添加第一个属性,其余的被忽略。虽然这是另一个问题。
答案 0 :(得分:2)
在使用BaseX时,您可以使用XQuery Update http://docs.basex.org/wiki/XQuery_Update,例如
copy $items := <root>
<list>
<title>foo</title>
<item>bar1</item>
<item>bar2</item>
</list>
<list>
<item>bar1</item>
<item>bar2</item>
</list>
</root>
modify (
for $item in $items/list/item
return insert node attribute {'id'} {count($item/(., preceding-sibling::item))} into $item
)
return $items
结果是
<root>
<list>
<title>foo</title>
<item id="1">bar1</item>
<item id="2">bar2</item>
</list>
<list>
<item id="1">bar1</item>
<item id="2">bar2</item>
</list>
</root>