2011-06-06 174 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