我试图模仿类似于HTML或lang
的{{1}}属性的解释。
给出以下XML块:
xml:lang
我在制定XPath 1.0表达式时遇到问题,该表达式返回特定语言的所有节点,让我们说<xml lang="c">
c#0
<para>c#1</para>
<para>c#2</para>
<para lang="d">
d#0
<para>d#1</para>
<para lang="c">c#3</para>
<para lang="d">
d#2
<para>d#3</para>
<para lang="c">c#4</para>
</para>
<para lang="c">
c#5
<para>c#6</para>
</para>
</para>
</xml>
。节点匹配类似于xpath c
函数匹配的lang()
属性:
xml:lang
的值为lang
(c
)//*[@lang = "c"]
属性,其值lang
(c
)//*[ancestor::*/@lang = "c"]
属性lang
属性定义为lang
以外的更多&#34;接近&#34;比具有c
属性lang
的父级(2.1是&#34;否决&#34; )。与上述XML的示例匹配和c
的{{1}}示例匹配将提供7个节点:c#0到c#6。
c
我在xpath查询中描述这个问题。在过去的一年里,即使我用xpath做得更好,这个真的让我失望了。
无论我尝试什么,我都有问题来描述一个祖先的覆盖性质,其中匹配谓词的祖先与不匹配的谓词。
给出的示例甚至只是问题的一半,因为不仅有完整的属性值匹配,而且还有起始的匹配:
lang
但我很高兴看到首先解决了推翻问题。我用PHP(Online Demo)测试:
<xml lang="c"> c#0 ... (direct match, lang="c")
<para>c#1</para> (parent has lang="c")
<para>c#2</para> (parent has lang="c")
<para lang="c">c#3</para> (direct match, lang="c")
<para lang="c">c#4</para> (direct match, lang="c")
<para lang="c"> c#5 ... (direct match, lang="c")
<para>c#6</para> (parent has lang="c", that parent is descending of
any other ancestor with lang="d")
答案 0 :(得分:2)
使用强>:
//*[@lang='c'
or
not(@lang) and ancestor::*[@lang][1]/@lang = 'c'
]
这将选择XML文档中具有值为lang
的{{1}}属性或没有"c"
属性且lang
的值的任何元素具有lang属性的第一个祖先的属性是lang
。
更简单的等效XPath表达式:
"c"
以下是使用XPath Visualizer 执行选择的快照:
答案 1 :(得分:1)
您预期的XPath
//*[(descendant-or-self::*/@lang = 'c' and not(descendant-or-self::*/@lang != 'c')) or (ancestor-or-self::*/@lang = 'c' and not(ancestor-or-self::*/@lang != 'c'))]
xml c#0 (lang: c)
para c#1 (lang: c)
para c#2 (lang: c)
para c#3 (lang: c)