【问题标题】:How to check if an attribute resides within an element?如何检查属性是否存在于元素中?
【发布时间】:2011-10-25 17:01:24
【问题描述】:

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

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

但是解析器抛出错误说:“轴名称后出现意外的标记“@””。谁能告诉我如何解决它或有另一种方法可以做到这一点?谢谢!

【问题讨论】:

    标签: xml xpath schematron


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      因此,我认为您正在文档中的任何位置查找具有@style 属性的任何元素。

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

      descendant::*[@style]
      

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

      descendant::*[@style]/@style
      

      它会为您找到所有样式属性本身。

      【讨论】:

      • descendant::* 会给出错误的答案,除非上下文节点是/,在这种情况下它等同于//*/descendant::*[@style]/@style 相当于/descendant::*/@style 相当于//*/@style 相当于//@style
      【解决方案3】:

      @Kirill 给出了关于如何修复的正确答案

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

      通过使用

      //@style
      

      但是对于那些想知道为什么初始 XPath 不起作用的人,以及是否有使用 self:: 的变体可以工作...

      请记住,@attribute:: 轴的缩写。所以self::@fooself::attribute::foo 的简写。但从句法上讲,定位步骤中只能有一个轴。这就是解析器拒绝 self::@style 的原因:它有两个轴。

      这里还有其他有趣的事情发生。您可能认为您可以将表达式修复如下:

      //@*[self::style]
      

      (暂时忽略这比//@style 更复杂的事实。当您想要所有属性除了style,例如//@*[not(self::style)] 时,您开始尝试这样的表达式。)

      这个表达式解析和运行没有错误。第一部分 //@* 匹配文档中的所有属性节点。您可能会认为(和我一样)谓词 [self::style] 将在其上下文节点是 style 属性时评估为真值。

      但我们会错的。如果我们尝试一下,我们会得到一个空的节点集。为什么?如果上下文节点是一个属性节点,并且self:: 轴仅包含上下文节点,并且属性的名称与self:: 之后的名称匹配,那么谓词中的表达式不应该将该属性节点作为其结果?

      在第页。 XSLT 2.0 和 XPath 2.0(第 4 版)的 1228,Self Axis 的词汇表定义解释:

      self轴的主节点种类elements,表示 当上下文节点是一个属性时,一个轴step 形成self::*self::xyz 不会选择该属性[粗体强调我的]。

      但是,在 XPath 2.0 中,您可以使用 self::attribute(style)。 IE。您可以使用 KindTest 而不是 NameTest。

      Michael Kay 详细介绍了 p 上的 NameTest 可以匹配哪些类型的节点的规则。 695.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-15
        • 1970-01-01
        • 2019-04-30
        • 2012-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多