这有效:
(//someparentpath/h3 | //someparentpath/ul/li/div)/somechildpath
这不是:(为什么?
//someparentpath/(h3 | ul/li/div)/somechildpath
答案 0 :(得分:9)
XPath 1.0的语法不允许在轴步骤中进行更改,请参阅specifications for node sets或尝试XPath 1.0 Grammar Test Page。语法允许您的第一个查询,第二个查询没有有效的XPath 1.0。
如果你有机会,切换到XPath 2.0 实现,它提供更多查询XML的可能性。您的两个查询都是有效的XPath 2.0语句。
在 XPath 1.0 中,您必须:
完全写出路径两次并使用它们的联合:
//someparentpath/h3/somechildpath | //someparentpath/ul/li/div/somechildpath
或允许的查询,最后用公共轴步骤 ,这至少要少一点重复:
(//someparentpath/h3 | //someparentpath/ul/li/div)/somechildpath
使用一些descending-or-self
- hack与harpo和JLRishe提出的谓词,但它们的共同点是你可能匹配的元素多于你想要的。
答案 1 :(得分:3)
我认为你能得到的最接近的是:
//someparentpath//*[self::h3 or self::div[parent::li/parent::ul]]/somechildpath
然而,正如harpo已经提到的那样,//
阻止它们完全等效,我认为在单个表达式中没有办法解决这个问题。请注意,如果您使用的是XSLT,则可以使用多个变量赋值来实现您要执行的操作并避免部分冗余:
<xsl:variable name="ppath" select="//someparentpath" />
<xsl:variable name="children" select="($ppath/h3 | $ppath/ul/div/li)/somechildpath" />
请注意您所描述的假设表达式:
//someparentpath/(h3 | ul/li/div)/somechildpath
XPath 2.0中允许。在XPath 1.0中根本不允许这样做,因为1.0不允许你在路径的中途使用表达式。
答案 2 :(得分:0)
好问题,我对自己的“为什么”感兴趣。
但实际上,你可以改写这个
//someparentpath/(h3 | ul/li/div)/somechildpath
这个(不太相同)
//someparentpath//*[self::h3 or self::ul/li/div]/somechildpath
这不是太糟糕了。
但是,我对此感到沮丧。