再次讨论节点集中的不同节点(基于属性值)。 想象一下,你有以下结构:
<struct>
<a>
<x id="1">a_1</x>
<x id="2">a_2</x>
<x id="3">a_3</x>
</a>
<b inherits="a">
<x id="2">b_2</x>
</b>
</struct>
<struct/>
可能包含多个元素,例如<b/>
,它们会继承相同的<a/>
。同时允许使用<a/>
等多个元素。 <a/>
和<b/>
的顺序是任意的。继承是单层深度的。
问题:如何创建单 XPath,为给定的<b/>
选择以下节点集:
<x id="1">a_1</x>
<x id="2">b_2</x>
<x id="3">a_3</x>
请注意第二行的b_2
值。
对此有何解决方案?
更新
resuting XPath应具有以下格式:b[(magic_xpath)[@id=2]='b_2']
,其中magic_xpath
从<x/>
和<a/>
s中选择不同的<b/>
。
现实生活<struct/>
可能如下所示:
<struct>
<a>
<x id="1">a_1</x>
<x id="2">a_2</x>
<x id="3">a_3</x>
</a>
<b inherits="a">
<x id="2">I don't match resulting XPath</x>
</b>
<b inherits="a">
<x id="2">b_2</x>
</b>
</struct>
答案 0 :(得分:1)
使用强>:
$vB/x
|
/*/*[name() = $vB/@inherits]
/x[not(@id = $vB/x/@id)]
其中$vB
被定义为b
元素。
这将选择{{1}的所有b/x
个元素和所有x
个子元素(id
属性不等于任何b/x/@id
属性)的并集} {(struct/*
的子项),其名称为struct
的值。
或者,根据OP在评论中的要求 - 没有变量:
b/@inherits
完成基于XSLT的验证:
/*/b/x
|
/*/*[name() = /*/b/@inherits]
/x[not(@id = /*/b/x/@id)]
将此转换应用于提供的(已更正为格式良好的)XML文档:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
"/*/b/x
|
/*/*[name() = /*/b/@inherits]
/x[not(@id = /*/b/x/@id)]
"/>
</xsl:template>
</xsl:stylesheet>
评估单个XPath表达式并输出所选节点:
<struct>
<a>
<x id="1">a_1</x>
<x id="2">a_2</x>
<x id="3">a_3</x>
</a>
<b inherits="a">
<x id="2">b_2</x>
</b>
</struct>