2011-06-06 175 views
1

很抱歉,但这里一共有XSLT小白XSLT限制父节点下的子节点的数量

由于XML看起来像:

<Foo> 
    <Bar /> 
    <Baz /> 
    <Qax /> 
    <FooBar /> 
</Foo> 

是否有一个XSLT,这将限制孩子的数量Foo下的节点只有3个?

+0

在哪个意义上“限制”?你想排除哪些元素?任何三岁以下? – 2011-06-06 13:00:30

+0

好问题,+1。查看我的答案,获得一个简单而完整的解决方案,使用最基本的XSLT设计模式之一 - 重写身份规则。 – 2011-06-06 13:08:02

+0

我也提供了详细的解释。 – 2011-06-06 13:12:08

回答

2

这种变换并重写身份规则/模板:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="/*/*[position() > 3]"/> 
</xsl:stylesheet> 

当所提供的XML文档应用:

的希望,正确的结果产生:

<Foo> 
    <Bar/> 
    <Baz/> 
    <Qax/> 
</Foo> 

说明

  1. identity rule /模板拷贝的每一个节点 “原样”。

  2. 我们只有一个重写身份规则是比3更大的位置上元素的子元素的任何额外的模板。这个模板没有任何东西(有一个空的主体),它有效地防止任何这样的元素被复制到输出(或者我们用它来说,“删除”它)。

请注意

  1. 使用并重写身份规则是最基本,最强大的XSLT设计模式

  2. 使用这种设计模式,建议在一个简单的<xsl:copy-of>因为它不仅允许被复制的节点,而是由我们提供的任何模板进行处理。所有元素的属性也被处理。

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

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

</xsl:stylesheet> 

得到:

<Foo> 
    <Bar/> 
    <Baz/> 
    <Qax/> 
</Foo> 
0

有三种方法这样做的:

首先,您可以指示处理该Foo元素只处理前三个子节点模板:

<xsl:template match="Foo"> 
    <xsl:copy> <!-- can substitute with 'Foo' in this instance --> 
    <xsl:apply-templates select="*[position() &lt;= 3]" /> 
    </xsl:copy> 
</xsl:template> 

或者,如果前三个孩子节点不需要任何个人治疗,您可以使用像这样的模板来处理孩子:

<xsl:template match="Foo/*[position() &lt;= 3]"> 
    <!-- process the child element here --> 
</xsl:template> 

这种方法的两个缺点是Foo的其余孩子可以通过其他模板进行处理,例如,如果您有一个专门处理FooBar节点的孩子,并且也没有简单的方法来区别对待您的BarBaz元素。

第三种方法是使用是第三个这样的后应用于Foo所有子节点的空模板:

<xsl:template match="Foo/*[position() &gt; 3]" /> 

此方法还为您提供了能够将单个模板的优势如果您需要,请致电BarBaz