【问题标题】:xslt match all nodes except a specific onexslt 匹配除特定节点之外的所有节点
【发布时间】:2013-03-20 13:57:42
【问题描述】:

我想匹配我的 xml 中的所有节点,除了一个,即 docbody。像

<xsl:template match="@*|node()[not(docBody)]" name="identity">
<xsl:copy>
  <xsl:apply-templates select="@*|node()">
</xsl:copy>
</xsl:template>

我是怎么做到的,我试过上面的方法。

【问题讨论】:

  • 问题是什么?
  • 我试图以这种方式排除节点,它不起作用,有没有办法在匹配中排除节点

标签: xml xslt


【解决方案1】:

匹配除此之外的所有模板(添加self::)并覆盖docBody 的默认模板(没有它,docBody 的内容仍将被打印):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />

<xsl:template match="@*|node()[not(self::docBody)]" name="identity">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<!-- overwrite the default template -->
<xsl:template match="docBody">
</xsl:template>

</xsl:stylesheet>

【讨论】:

  • 要排除 cmets,XPath 会分别是 @*|node()[not(self::comment())] 还是 @*|node()[not(//comment())]
【解决方案2】:

您的匹配条件是“任何没有docBody 元素child 的节点”,这与不是docBody 元素本身 不同。你想要这个:

<xsl:template match="@*|node()[not(self::docBody)]" name="identity">

虽然你应该只使用两个模板:

<xsl:template match="docBody"/>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

【讨论】:

    【解决方案3】:

    是的,您只需要这样做:

    <xsl:template match="@*|node()[not(self::docBody)]" name="identity">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()">
      </xsl:copy>
    </xsl:template>
    

    【讨论】: