2011-08-12 161 views
2

我想检查文档中是否有内联样式表,但我不确定如何挑选元素的后代属性,因为“样式”属性可以附加到主体元素中的任何元素。这是当前的XPath我写:如何检查一个属性是否在一个元素中?

descendant::@*[self::@style] 

但是解析器抛出错误说:“意外令牌‘@’轴名后”。任何人都可以告诉我如何解决这个问题,或者有另一种方法来解决这个问题?谢谢!

回答

3

所以,你有一个@style属性我想在文档内的任何地方寻找任何元素。

如果你想包含要下列属性的元素:

descendant::*[@style] 

这将返回有一个@style属性的当前节点的所有后代元素。如果你想要属性本身,你最好使用类似的东西:

descendant::*[@style]/@style 

这会找到你自己的所有样式属性。

+0

你是对的,这是一个更好的解决方案。谢谢! – Michael

+0

'descendant :: *'会给出错误的答案,除非上下文节点是'/',在这种情况下,它相当于'// *'。 '/ descendant :: * [@ style]/@ style'等价于'/ descendant :: */@ style'等价于'// */@ style'等同于'// @ style'。 – LarsH

2

使用这个XPath://@style,它会选择所有属性style

+0

+1。这是更好的答案。 – LarsH

0

@Kirill了关于如何解决正确答案通过

descendant::@*[self::@style] 

使用

//@style 

但是,对于那些想知道谁为什么最初的XPath不工作,以及是否有一个变种使用self::,这将工作...

请记住,@是一个ab轴的缺省值为attribute::。所以self::@fooself::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.

相关问题