我想检查文档中是否有内联样式表,但我不确定如何挑选元素的后代属性,因为“样式”属性可以附加到主体元素中的任何元素。这是当前的XPath我写:如何检查一个属性是否在一个元素中?
descendant::@*[self::@style]
但是解析器抛出错误说:“意外令牌‘@’轴名后”。任何人都可以告诉我如何解决这个问题,或者有另一种方法来解决这个问题?谢谢!
我想检查文档中是否有内联样式表,但我不确定如何挑选元素的后代属性,因为“样式”属性可以附加到主体元素中的任何元素。这是当前的XPath我写:如何检查一个属性是否在一个元素中?
descendant::@*[self::@style]
但是解析器抛出错误说:“意外令牌‘@’轴名后”。任何人都可以告诉我如何解决这个问题,或者有另一种方法来解决这个问题?谢谢!
所以,你有一个@style
属性我想在文档内的任何地方寻找任何元素。
如果你想包含要下列属性的元素:
descendant::*[@style]
这将返回有一个@style
属性的当前节点的所有后代元素。如果你想要属性本身,你最好使用类似的东西:
descendant::*[@style]/@style
这会找到你自己的所有样式属性。
@Kirill了关于如何解决正确答案通过
descendant::@*[self::@style]
使用
//@style
但是,对于那些想知道谁为什么最初的XPath不工作,以及是否有一个变种使用self::
,这将工作...
请记住,@
是一个ab轴的缺省值为attribute::
。所以self::@foo
是self::attribute::foo
的简写。但从语法上来说,在一个位置步骤中只能有一个轴。这就是解析器拒绝self::@style
的原因:它有两个轴。
这里还有其他有趣的事情发生。你可能会认为你能解决这个表达式如下:
//@*[self::style]
(暂时忽略的事实,这是不必要的更复杂,//@style
当你想除了style
所有属性你开始尝试这样的表情,例如//@*[not(self::style)]
。)
该表达式解析并运行时没有错误。第一部分//@*
匹配文档中的所有属性节点。你可能会认为(和我一样),谓词[self::style]
只要其上下文节点为style
属性就会评估为真值。
但是我们会错的。如果我们尝试它,我们会得到一个空的节点集。为什么?如果上下文节点是属性节点,并且轴仅包含上下文节点,并且属性的名称与self::
之后的名称匹配,那么谓词中的表达式是否应该让该属性节点作为其结果?
On p。 XSLT 2.0和XPath 2.0(第4版)的1228,自轴的术语定义解释:
的主要节点的自轴的样是元件,这意味着 ,当上下文节点是属性,所述 形式的轴线步骤
self::*
或self::xyz
将不选择该属性[粗体强调矿。
但是,在XPath 2.0中,您可以使用self::attribute(style)
。即你可以使用KindTest而不是NameTest。
迈克尔凯详细说明了哪些节点可以通过p上的NameTest进行匹配的规则。 695.
你是对的,这是一个更好的解决方案。谢谢! – Michael
'descendant :: *'会给出错误的答案,除非上下文节点是'/',在这种情况下,它相当于'// *'。 '/ descendant :: * [@ style]/@ style'等价于'/ descendant :: */@ style'等价于'// */@ style'等同于'// @ style'。 – LarsH