有没有人知道如何只复制xml文件中的前n个节点并使用xslt删除其余节点?所以说我只想复制前10个节点并删除属于同一父节点的其余节点。
答案 0 :(得分:3)
您应该将它们从结果集中删除,如:
<!-- note you must to encode 'greater than' and 'lower than' characters -->
<xsl:for-each select="parent/nodes[position() <= 10]">
...
</xsl:for-each>
答案 1 :(得分:3)
将以下模板添加到身份转换中:
<xsl:template match="/*/*[position() < 11]"/>
工作原理:身份转换以递归方式将其匹配的任何节点复制到结果文档。但是身份变换的匹配标准具有最低优先级;如果某个节点与任何具有更高优先级的模板匹配,则将使用该模板。 (优先级规则不明确,但它们的设计非常好,您很少需要了解它们;一般来说,如果一个节点由两个模板匹配,XSLT将选择模式更具体的模板。)
在这种情况下,我们说如果一个节点是一个元素,它是顶级元素的子元素(顶级元素是根目录下的第一个元素,或/*
及其子元素因此/*/*
)元素在节点列表中的位置为11或更高,不应复制。
修改强>
OOF。除了最重要的事情之外,上述所有内容都是正确的。我写的内容将复制前十个除之外的顶级元素的每个孩子。
以下是您需要的完整(且正确)的模板版本:
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*/*[position() > 10]"/>
就是这样。第一个模板复制第二个模板不匹配的所有内容。第二个模板匹配前10个之后的所有元素,并且不对它们执行任何操作,因此它们不会被复制到输出中。
答案 2 :(得分:1)
很抱歉,代码未在下面正确粘贴。这应该是:
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="inner"/>
<xsl:template match="/*/*[position() < 11]">
<xsl:call-template name="identity"/>
</xsl:template>
答案 3 :(得分:0)
使用标识转换,它将源树复制到输出树,并添加模板以排除要消除的元素。然后,因为你不想消除它们的所有而只是那些在前十个之后的那些,根据它们的位置为要允许的特殊模板添加一个最终模板:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="inner"/>
<xsl:template match="inner[position() < 11]">
<xsl:call-template name="identity"/>
</xsl:template>
</xsl:stylesheet>
与XML一起使用
<?xml version="1.0" encoding="UTF-8"?>
<outer>
<inner foo="1"/>
<inner foo="2"/>
<inner foo="3"/>
<inner foo="4"/>
<inner foo="5"/>
<inner foo="6"/>
<inner foo="7"/>
<inner foo="8"/>
<inner foo="9"/>
<inner foo="10"/>
<inner foo="11"/>
<inner foo="12"/>
<inner foo="13"/>
<inner foo="14"/>
</outer>