首页 > 解决方案 > 使用 XSLT 复制前 N 个节点及其子节点

问题描述

我有一个包含 CD 目录的 XML 文档:

<?xml version="1.0"?>
<catalog>
  <cd><title>Greatest Hits 1999</title><artits>Various Artists</artist></cd>
  <cd><title>Greatest Hits 2000</title></cd>
  <cd><title>Best of Christmas</title></cd>
  <cd><title>Foo</title></cd>
  <cd><title>Bar</title></cd>
  <cd><title>Baz</title></cd>
  <!-- hundreds of additional <cd> nodes -->
</catalog>

我想使用 XSLT 1.0 创建此 XML 文档的摘录,其中仅包含第一个 N<cd>节点,以及它们的父节点和子节点。比方说N=2;这意味着我期望以下输出:

<?xml version="1.0"?>
<catalog>
  <cd><title>Greatest Hits 1999</title><artits>Various Artists</artist></cd>
  <cd><title>Greatest Hits 2000</title></cd>
</catalog>

我找到了这个答案,我从中改编了以下样式表:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>

  <xsl:param name="count" select="2"/>

  <!-- Copy everything, except... -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <!-- cd nodes that have a too large index -->
  <xsl:template match="cd[position() &gt;= $count]" />

</xsl:stylesheet>

当我尝试应用此样式表时,我收到以下错误:Forbidden variable: position() >= $count.
当我$count用文字替换时2,输出包含完整的输入文档,有数百个<cd>节点。

如何使用 XSLT 从我的 XML 文档中获取仍然有效的 XML 的摘录,但只是抛出了一堆节点?我正在寻找一种通用的解决方案,它也适用于不像我的示例那样简单的文档结构。

标签: xmlxsltxslt-1.0

解决方案


为什么不简单地:

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

<xsl:param name="count" select="2"/>

<xsl:template match="/catalog">
    <xsl:copy>
        <xsl:copy-of select="cd[position() &lt;= $count]"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

如果您想使其通用(这在实践中很少起作用,因为 XML 文档有多种结构),请尝试以下操作:

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

<xsl:param name="count" select="2"/>

<xsl:template match="/*">
    <xsl:copy>
        <xsl:copy-of select="*[position() &lt;= $count]"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

推荐阅读