XPath for xml:lang?测试属性自身轴失败

时间:2015-03-04 19:37:00

标签: xml xslt xpath

上下文是使用

进行的XSLT身份转换
<xsl:template match="abstract[@xml:lang]">
    <xsl:copy>
       <xsl:apply-templates select="@*[not(self::xml:lang)]|node()"/>
    </xsl:copy>
</xsl:template>

所以,我希望删除属性xml:lang

3 个答案:

答案 0 :(得分:2)

您应该看到以下警告:

  

警告!自轴永远不会选择任何元素节点   从属性节点开始

您可以改为测试属性&#39; name()

  <xsl:template match="abstract[@xml:lang]">
    <xsl:copy>
      <xsl:apply-templates select="@*[name() != 'xml:lang']|node()"/>
    </xsl:copy>
  </xsl:template>

这将有效地从xml:lang按要求删除abstract属性。

答案 1 :(得分:2)

自动轴上永远不会有属性(除非您使用libxslt处理器......)。
见下文评论中的讨论

为什么你不做:

<xsl:template match="abstract/@xml:lang"/>

要特别禁止不需要的属性


工作演示:http://xsltransform.net/eiZQaFp

答案 2 :(得分:2)

这里的问题是self::[QName]只能引用元素,而不是属性 1

我认为michael.hor257k的建议对于这个特殊情况是最好的,并且在这个特殊情况下检查kjhughes的答案中的名称应该没问题,因为它是关于xml命名空间,这是明确的。< / p>

但一般情况下,如果您想在不依赖name()的情况下排除单个属性,则可以执行以下操作:

<xsl:template match="abstract[@xml:lang]">
    <xsl:copy>
       <xsl:apply-templates select="@*[(. | ../@xml:lang)[2]]|node()"/>
    </xsl:copy>
</xsl:template>

http://xsltransform.net/eiZQaFp/2

只有xml:lang属性存在时才能正常运行,但此处match属性中的模式确保它确实存在。


  1. 以下是XPath规范中的相关文本,解释了为什么这是真的:
  2.   

    每个轴都有一个主节点类型。如果一个轴可以包含元素,那么主节点类型就是元素;否则,它是轴可以包含的节点类型。因此,

         
        
    • 对于属性轴,主节点类型是属性。
    •   
    • 对于名称空间轴,主节点类型是名称空间。
    •   
    • 对于其他轴,主节点类型为element。
    •   
         

    当且仅当节点的类型(参见[5数据模型])是主节点类型并且扩展名等于QName指定的扩展名时,作为QName的节点测试才为真。 。例如,child :: para选择上下文节点的para元素子节点;如果上下文节点没有para子节点,它将选择一组空节点。 attribute :: href选择上下文节点的href属性;如果上下文节点没有href属性,它将选择一组空节点。

    self::的主要节点类型是元素,因此如果后跟QName(例如xml:lang),则self::xml:lang只能引用元素,而不是属性