XSLT用于限制父节点下的子节点数

时间:2011-06-06 12:58:48

标签: xml xslt

抱歉,这里总共有xslt noob

给定XML:

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

是否有一个XSLT会限制Foo下的子节点数量,因此只有3个?

3 个答案:

答案 0 :(得分: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 />
    <FooBar />
</Foo>

产生了想要的正确结果:

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

<强>解释

  1. identity rule /模板“按原样”复制每个节点。

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

  3. 请注意

    1. 使用和覆盖身份规则是最基本,最强大的XSLT设计模式

    2. 建议在简单的<xsl:copy-of> 上使用此设计模式,因为它不仅可以复制节点,还可以由我们提供的任何模板进行处理。还处理所有元素的属性。

答案 1 :(得分: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>

答案 2 :(得分: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应用单个模板的优势。