Xml XPath拉多个匹配项 (BaseX)错误
我正在BaseX中的一个大数据集上运行查询,但一个XQuery正在使我的程序崩溃,出现错误Xml XPath拉多个匹配项 (BaseX)错误,xml,xpath,xquery,Xml,Xpath,Xquery,我正在BaseX中的一个大数据集上运行查询,但一个XQuery正在使我的程序崩溃,出现错误[XPTY0004]项预期,找到序列:(属性begin{“6”},…) 在我的查询中,我试图通过比较begin(XML中的一个属性)和number()来确保一个元素位于另一个元素之前。但每当我在我的数据集上尝试最基本的XQuery(返回匹配节点)(例如with)时,我都会得到一个类似于我以前遇到的错误: [错误]SaxonCE.XSLT20Processor 14:08:39.692严重:XPathExce
[XPTY0004]项预期,找到序列:(属性begin{“6”},…)
在我的查询中,我试图通过比较begin
(XML中的一个属性)和number()
来确保一个元素位于另一个元素之前。但每当我在我的数据集上尝试最基本的XQuery(返回匹配节点)(例如with)时,我都会得到一个类似于我以前遇到的错误:
[错误]SaxonCE.XSLT20Processor 14:08:39.692严重:XPathException在中
invokeTransform:不允许包含多个项的序列作为
number()的第一个参数(“6”,“10”)
因此,我猜测节点的兄弟节点有问题,也就是说,这些节点不止一个,而且不清楚应该比较哪一个。下面是一些例子
为什么顺序很重要?
XPath用于树库的查询引擎:语言注释语料库。在某些情况下,我们希望节点按顺序匹配,有时这并不重要。举一个简单的例子:有时我们想要匹配一些特定的东西,比如关注的人,其中冠词、形容词、名词的顺序很重要。在其他查询中,这并不重要,我们还希望匹配诸如可用时间之类的短语,其中冠词、形容词、名词的顺序可以是任意顺序
换句话说,在第一种情况下,元素的顺序应该得到尊重,在第二种情况下则不应该。下面是包含冠词、形容词和名词的此类结构的可能XPath表示
node[@cat="np" and node[@pt="art"] and node[@pt="adj"] and node[@pt="n"]]
默认情况下,XPath不关心这些元素的顺序,而是进行贪婪搜索,即它还将匹配可用时间等项(art
,n
,adj
)。但是我想重新编写上面的XPath,以确保节点的顺序得到尊重,因此相关人员(art
,n
,adj
)不匹配可用时间(art
,adj
,n
)等结构
此XPath应匹配:
/node/node[number(@begin) < number(../node/@begin)]
资料
但是需要遵循XPath的顺序,即
//node[
@cat="np" and
not(node[
position() < last()
][number(@begin) > following-sibling::node/number(@begin)]) and
node[
@rel="det" and
@pt="vnw" and
@lemma="die"
] and
count(node[
@rel="mod" and
@pt="adj"
]) > 1
]
但是,我希望这个cat=“np”
匹配,并使not()
函数不那么具有攻击性,即只需要XPath中指定的节点(在本例中是rel=“det”pt=“vnw”lemma=“die”
,以及两个rel=“mod”pt=“adj”
节点)遵循顺序要求,其中begin属性应小于XPath结构的下一项。允许XPath中未指定的cat=“np”
中的其他项具有大于其下一个同级项的属性
请注意,XPath结构的最后一项(与示例XML中的id=“11”
相匹配)不一定要有一个begin属性,该属性低于其XML中的后续节点(XPath中未指定)
和前面一样,我对如何使用纯XPath选项解决这个问题特别感兴趣,但也欢迎使用XQuery替代方案。最好是将XPath结构作为输入,并将“字顺序”应用于最顶层节点及其所有子节点的函数。鼓励使用此处所示的XPath示例代码和用法。我想我理解您的问题的一部分是: 假设我想匹配XML,其中根的每个直接子级都有一个比下一个同级小的属性begin
此XPath应匹配:
/node/node[number(@begin) < number(../node/@begin)]
/node/node[number(@begin)
现在,很清楚为什么这会给你一个错误。在谓词中,。
选择id=0的节点,它有三个子节点(id为1、4和6),每个子节点都有一个@begin
属性,因此number(../node/@begin)
正在选择一个由三个属性组成的序列
您的查询似乎与散文需求没有任何关系,即
其中,根的每个直接子级都有一个小于下一个同级的属性begin
这样做的条件是
节点[position()lt last()]中的每$n满足
(编号($n/@begin)lt编号($n/以下同级::node/@begin)]
关于您面临的a-sequence-of-more-item-is-not-allowed异常,请注意XPath 2.0及更高版本和XQuery支持在路径步骤(../number()
)上调用函数。也就是说,您可以调用number()
在单个节点上
一次传递一个开始
属性以避免异常:
/node/node[number(@begin) < ../node/number(@begin)]
“一种方法是使用语料库中可用的
begin
属性的数字比较。它是数字升序,因此如果我们想确保XPath的顺序是完整的,我们可以使用@cat=“np”
说的每个子节点的数值应该小于下一个节点的数值。”
如果我理解正确,您可以使用以下XPath:
/node/node[
not(
node[position() < last()]
[number(@begin) > following-sibling::node/number(@begin)]
)
]
只会选择第二级节点
,因为它是唯一一个按升序具有begin
属性值的第二级节点
:
<node id="0" begin="1" cat="np">
<node id="1" begin="1" pt="art" text="the"/>
<node id="2" begin="2" pt="adj" text="concerned"/>
<node id="3" begin="3" pt="n" text="man"/>
</node>
因此,完整的表达式如下所示:
//node[@cat="np" and
not(node[(@rel="det" and @pt="vnw" and @lemma="die") or (@rel="mod" and @pt="adj")]
[position() < last()]
[number(@begin) >
following-sibling::node[
(@rel="det" and @pt="vnw" and @lemma="die") or (@rel="mod" and @pt="adj")
]/number(@begin)
]
)
and node[@rel="det" and @pt="vnw" and @lemma="die"]
and count(node[@rel="mod" and @pt="adj"]) > 1
]
//节点[@cat=“np”和
不是(节点[(@rel=“det”和@pt=“vnw”和@lemma=“die”)或(@rel=“mod”和@pt=“adj”)]
[位置()
以下同级::节点[
(@rel=“det”和@pt=“vnw”和@lemma=“die”)或(@rel=“mod”和@pt=“adj”)
]/编号(@begin)
]
)
节点[@rel=“det”和@pt=“vnw”以及@lemma=“die
<node begin="4" cat="np" id="8" rel="obj1">
<node begin="4" id="9" pos="det" pt="vnw" rel="det" word="die" lemma="die" />
<node begin="5" id="10" pos="adj" pt="adj" rel="mod" word="veelzijdige" />
<node begin="6" id="11" pos="adj" pt="adj" rel="mod" word="getalenteerde" />
<node begin="7" id="12" pos="noun" pt="n" rel="hd" word="figuren" />
<node begin="8" id="31" index="1" rel="obj1" />
<node begin="2" id="32" index="2" rel="obj2" />
</node>
<node id="0" begin="2">
<node id="1" begin="2">
<node id="2" begin="2"/>
<node id="3" begin="3"/>
</node>
<node id="4" begin="5">
<node id="5" begin="5"/>
</node>
<node id="6" begin="6"/>
</node>
/node/node[number(@begin) < number(../node/@begin)]
/node/node[number(@begin) < ../node/number(@begin)]
for $node in node[
every $n in node[position() lt last()]
satisfies not($n/following-sibling::node[number(@begin) lt number($n/@begin)])
]
return $node
/node/node[
not(
node[position() < last()]
[number(@begin) > following-sibling::node/number(@begin)]
)
]
<node id="0" begin="2">
<node id="0" begin="1" cat="np">
<node id="1" begin="1" pt="art" text="the" />
<node id="2" begin="3" pt="n" text="time" />
<node id="3" begin="2" pt="adj" text="available" />
</node>
<node id="0" begin="1" cat="np">
<node id="1" begin="1" pt="art" text="the" />
<node id="2" begin="2" pt="adj" text="concerned" />
<node id="3" begin="3" pt="n" text="man" />
</node>
</node>
<node id="0" begin="1" cat="np">
<node id="1" begin="1" pt="art" text="the"/>
<node id="2" begin="2" pt="adj" text="concerned"/>
<node id="3" begin="3" pt="n" text="man"/>
</node>
node[(@rel="det" and @pt="vnw" and @lemma="die") or (@rel="mod" and @pt="adj")]
[position() < last()]
[number(@begin) >
following-sibling::node[(@rel="det" and @pt="vnw" and @lemma="die") or (@rel="mod" and @pt="adj")]/number(@begin)
]
//node[@cat="np" and
not(node[(@rel="det" and @pt="vnw" and @lemma="die") or (@rel="mod" and @pt="adj")]
[position() < last()]
[number(@begin) >
following-sibling::node[
(@rel="det" and @pt="vnw" and @lemma="die") or (@rel="mod" and @pt="adj")
]/number(@begin)
]
)
and node[@rel="det" and @pt="vnw" and @lemma="die"]
and count(node[@rel="mod" and @pt="adj"]) > 1
]