使用 XSLT 复制前 N 个节点及其子节点
Copy first N nodes and their children with XSLT
我有一份 XML 包含 CD 目录的文档:
<?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>
我发现 this answer,我从中改编了以下样式表:
<?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() >= $count]" />
</xsl:stylesheet>
当我尝试应用此样式表时,出现以下错误:Forbidden variable: position() >= $count
。
当我用文字 2
替换 $count
时,输出包含完整的输入文档,有数百个 <cd>
节点。
如何使用仍然有效 XML 的 XSLT 从我的 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="/catalog">
<xsl:copy>
<xsl:copy-of select="cd[position() <= $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() <= $count]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我有一份 XML 包含 CD 目录的文档:
<?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>
我发现 this answer,我从中改编了以下样式表:
<?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() >= $count]" />
</xsl:stylesheet>
当我尝试应用此样式表时,出现以下错误:Forbidden variable: position() >= $count
。
当我用文字 2
替换 $count
时,输出包含完整的输入文档,有数百个 <cd>
节点。
如何使用仍然有效 XML 的 XSLT 从我的 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="/catalog">
<xsl:copy>
<xsl:copy-of select="cd[position() <= $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() <= $count]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>