XSLT过滤并选择第一个元素

时间:2014-12-08 15:42:06

标签: xml xslt xslt-2.0

我有一个xml文件,如:

<work>
  <job name="dummy">
    <task>template</task>
    <user>template</user>
  </job>
  <job name="unit1">
    <task>abc</task>
    <user>def</user>
  </job>
  <job name="unit2">
    <task>abc1</task>
    <user>xyz</user>
  </job>
</work>

我想删除除名字不是“虚拟”的第一个作业之外的所有元素。某些文件可能包含也可能不包含名称为“dummy”的作业。所以最终转换的文件应该是,

<work>
  <job name="unit1">
    <task>abc</task>
    <user>def</user>
  </job>
</work>

如何在xslt中过滤和选择?

2 个答案:

答案 0 :(得分:2)

最简单的方法是

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/*">
    <xsl:copy>
      <!-- copy the first job-whose-name-is-not-dummy -->
      <xsl:copy-of select="job[not(@name = 'dummy')][1]" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

如果这是更大转型的一部分,另一种思考方式就是考虑你想忽略的东西而不是你想要保留的东西:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <!-- copy everything as-is unless overridden -->
  <xsl:template match="@*|node()">
    <xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy>
  </xsl:template>

  <!-- ignore jobs named dummy -->
  <xsl:template match="job[@name = 'dummy']" />

  <!-- ignore jobs *not* named dummy, apart from the first one -->
  <xsl:template match="job[not(@name = 'dummy')][position() &gt; 1]" />

</xsl:stylesheet>

这样,如果您想要使用想要保留的job元素进行直接复制,您可以定义更多模板。

答案 1 :(得分:2)

您可以使用

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

<xsl:template match="job[@name = 'dummy'] | job[not(@name = 'dummy')][position() > 1]"/>