2010-09-21 21 views
0

我正在使用XSLT來遞歸一些XML,然後將一些HTML應用於輸出。它會緩存數據,但它會複製父項描述,我不知道爲什麼?我確信它在我面前是正確的,但我沒有看到它。它在<ul>標籤之後插入到XML中的下一級。當我遞歸XML時,XSLT正在複製一個描述

XML示例:

<root> 
    <filters> 
     <filter ID="My Test"> 
      <item id="1"> 
       <description>MyTest Descrip</description> 
       <item id="1"> 
        <description>Sub Level - 1</description> 
       </item> 
       <item id="2"> 
        <description>Sub Level - 2</description> 
       </item> 
       <item id="3"> 
        <description>Sub Level - 3</description> 
       <item id="4"> 
       <description>Sub Level 2 - 1</description> 
       </item> 
        <item id="5"> 
        <description>Sub Level 2 - 2</description> 
        </item> 
       </item> 
      </item> 
     </filter> 
    </filters> 
</root> 

XSLT示例:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> 
<xsl:output method="xml" indent="yes"/> 
<xsl:template match="filter"> 
    <xsl:variable name="dataID" select="@ID"/> 
     <ul class="searchdata"> 
      <xsl:apply-templates select="item"/> 
     </ul> 
    </xsl:template> 
    <xsl:template match="item"> 
    <li> 
     <xsl:variable name="searchID" select="@id"/> 
     <input id="{$searchID}" type="checkbox"/> 
     <label for="{$searchID}"> 
      <xsl:value-of select="description"/> 
     </label> 
     <xsl:if test="item"> 
     <ul> 
      <xsl:apply-templates /> 
     </ul> 
     </xsl:if> 
    </li> 
</xsl:template> 
</xsl:stylesheet> 

HTML輸出:

<?xml version="1.0" encoding="utf-8"?> 

    <ul class="searchdata"><li><input id="1" type="checkbox" /><label for="1">MyTest Descrip</label><ul> 
    MyTest Descrip 
    <li><input id="1" type="checkbox" /><label for="1">Sub Level - 1</label></li> 
    <li><input id="2" type="checkbox" /><label for="2">Sub Level - 2</label></li> 
      <li><input id="3" type="checkbox" /><label for="3">Sub Level - 3</label><ul> 
       Sub Level - 3 
       <li><input id="4" type="checkbox" /><label for="4">Sub Level 2 - 1</label></li> 

       <li><input id="5" type="checkbox" /><label for="5">Sub Level 2 - 2</label></li> 
      </ul></li> 
    </ul></li></ul> 

任何建議,將不勝感激。

謝謝。

回答

2

問題是你沒有注意到關於built-in rules,特別是文本節點和元素的內置規則。

<xsl:template match="*|/"> 
    <xsl:apply-templates/> 
</xsl:template> 

<xsl:template match="text()|@*"> 
    <xsl:value-of select="."/> 
</xsl:template> 

所以,你需要添加這條文本節點規則:

<xsl:template match="text()"/> 

然後你的輸出將是:

<ul class="searchdata"> 
    <li> 
     <input id="1" type="checkbox" /> 
     <label for="1">MyTest Descrip</label> 
     <ul> 
      <li> 
       <input id="1" type="checkbox" /> 
       <label for="1">Sub Level - 1</label> 
      </li> 
      <li> 
       <input id="2" type="checkbox" /> 
       <label for="2">Sub Level - 2</label> 
      </li> 
      <li> 
       <input id="3" type="checkbox" /> 
       <label for="3">Sub Level - 3</label> 
       <ul> 
        <li> 
         <input id="4" type="checkbox" /> 
         <label for="4">Sub Level 2 - 1</label> 
        </li> 
        <li> 
         <input id="5" type="checkbox" /> 
         <label for="5">Sub Level 2 - 2</label> 
        </li> 
       </ul> 
      </li> 
     </ul> 
    </li> 
</ul> 

而且,這個樣式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="item"/> 
    <xsl:template match="item[1]"> 
     <ul class="searchdata"> 
      <xsl:apply-templates select="../item" mode="li"/> 
     </ul> 
    </xsl:template> 
    <xsl:template match="item" mode="li"> 
     <li> 
      <input id="{@id}" type="checkbox"/> 
      <xsl:apply-templates/> 
     </li> 
    </xsl:template> 
    <xsl:template match="description"> 
     <label for="{../@id}"> 
      <xsl:value-of select="."/> 
     </label> 
    </xsl:template> 
</xsl:stylesheet> 

備註:這個規則顯式地匹配description元素,其優先級高於內置的元素模板規則(將模板應用於子節點)。

而在去年,這個樣式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="node()"> 
     <xsl:apply-templates select="node()[1]|following-sibling::node()[1]"/> 
    </xsl:template> 
    <xsl:template match="item[1]"> 
     <ul class="searchdata"> 
      <xsl:call-template name="item"/> 
     </ul> 
    </xsl:template> 
    <xsl:template match="item" name="item"> 
     <li> 
      <input id="{@id}" type="checkbox"/> 
      <xsl:apply-templates select="node()[1]"/> 
     </li> 
     <xsl:apply-templates select="following-sibling::node()[1]"/> 
    </xsl:template> 
    <xsl:template match="description"> 
     <label for="{../@id}"> 
      <xsl:value-of select="."/> 
     </label> 
     <xsl:apply-templates select="following-sibling::node()[1]"/> 
    </xsl:template> 
</xsl:stylesheet> 

注意:本用了順( 「最細粒度穿越」),而不是遞歸模板應用。

+0

Alejandro ....不知道我明白你的意思嗎?感謝您的迴應。 – scarpacci 2010-09-21 23:48:24

+0

@Alejandro:+1提供幾種解決方案,解釋內置模板和細粒度遍歷。 – 2010-09-22 00:40:44

+0

非常感謝Alejandro ....非常棒。 – scarpacci 2010-09-22 01:00:43