2011-11-19 69 views
0

可用的XSLT是1.0。我可以为嵌套类别制作这个XSLT吗?

下面的XML和XSLT用于构建嵌套类别的下拉导航菜单。类别的级别可能会有所不同。

示例XML:

<data> 
    <categories-nav> 
    <section id="11" handle="categories-1">Categories 1</section> 
    <entry id="65"> 
     <name handle="air-rifles">Air Rifles</name> 
     <subcategories field-id="50" subsection-id="12" items="2"> 
     <item id="66" quantity="1"> 
      <name handle="rifles">Rifles</name> 
      <active>Yes</active> 
      <subcategories field-id="57" subsection-id="13" items="2"> 
      <item id="67" quantity="1"> 
       <name handle="b2-series">B2 Series</name> 
       <active>Yes</active> 
      </item> 
      <item id="112" quantity="1"> 
       <name handle="junior-supergrade">Junior Supergrade</name> 
       <active>Yes</active> 
      </item> 
      </subcategories> 
     </item> 
     <item id="111" quantity="1"> 
      <name handle="accessories">Accessories</name> 
      <active>Yes</active> 
      <subcategories field-id="57" subsection-id="13" items="0" /> 
     </item> 
     </subcategories> 
    </entry> 
    <entry id="118"> 
     <name handle="pistols">Pistols</name> 
    </entry> 
    <entry id="58"> 
     <name handle="bb-softair-guns">BB Softair Guns</name> 
    </entry> 
    </categories-nav> 
</data> 

我现在的XSLT:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template name="categories-nav-entries" mode="navigation"> 
    <li class="{name/@handle}-{@id}"> 
     <a href="/cat/{@id}/{name/@handle}/"><xsl:value-of select="name"/></a> 
     <xsl:apply-templates select="subcategories" mode="navigation"/> 
    </li> 
</xsl:template> 

<!-- level 1 --> 

<xsl:template match="/data/categories-nav" mode="navigation"> 
    <ul> 
     <xsl:apply-templates select="entry" mode="navigation"/> 
    </ul> 
</xsl:template> 

<xsl:template match="/data/categories-nav/entry" mode="navigation"> 
    <xsl:call-template name="categories-nav-entries" mode="navigation"/> 
</xsl:template> 

<!-- level 2 --> 

<xsl:template match="/data/categories-nav/entry/subcategories" mode="navigation"> 
    <ul> 
     <xsl:apply-templates select="item" mode="navigation"/> 
    </ul> 
</xsl:template> 

<xsl:template match="/data/categories-nav/entry/subcategories/item" mode="navigation"> 
    <xsl:call-template name="categories-nav-entries" mode="navigation"/> 
</xsl:template> 

<!-- level 3 --> 

<xsl:template match="/data/categories-nav/entry/subcategories/item/subcategories" mode="navigation"> 
    <ul> 
     <xsl:apply-templates select="item" mode="navigation"/> 
    </ul> 
</xsl:template> 

<xsl:template match="/data/categories-nav/entry/subcategories/item/subcategories/item" mode="navigation"> 
    <xsl:call-template name="categories-nav-entries" mode="navigation"/> 
</xsl:template> 

</xsl:stylesheet> 

三个不同层次的比赛之间的唯一区别是重复subcategoriesitem节点。

我已经成功地在自己的命名模板中获得了li,但是有没有办法可以避免单独匹配三个级别?

另外,它似乎是因为我在初始匹配时使用了一种模式,所以我也必须在随后的所有匹配中使用该模式 - 是对的吗?

编辑:这里就是我想出了使用相对路径作为@迈克尔的回答后:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template name="categories-nav-list"> 
    <li class="{name/@handle}"> 
     <a href="/cat/{@id}/{name/@handle}/"><xsl:value-of select="name"/></a> 
     <xsl:apply-templates select="subcategories[@items > 0]"/> 
    </li> 
</xsl:template> 

<xsl:template match="categories-nav"> 
    <ul> 
     <xsl:apply-templates select="entry"/> 
    </ul> 
</xsl:template> 

<xsl:template match="categories-nav/entry"> 
    <xsl:call-template name="categories-nav-list"/> 
</xsl:template> 

<xsl:template match="categories-nav//subcategories[item/active='Yes']"> 
    <ul> 
     <xsl:apply-templates select="item"/> 
    </ul> 
</xsl:template> 

<xsl:template match="categories-nav//subcategories/item[active='Yes']" priority="1"> 
    <xsl:call-template name="categories-nav-list"/> 
</xsl:template> 

<xsl:template match="categories-nav//subcategories/item" priority="0"/> 

</xsl:stylesheet> 
+1

所有你'的xsl:用'mode'属性呼叫template'指令在XSLT语法非法的(如:\t'的'和另外两个) - 您的转换引发错误,无法处理。请改正。 –

+0

@DimitreNovatchev,谢谢 - 我没有得到错误,所以不知道。已删除模式。 –

回答

0

你并不需要把绝对路径中的每个@match属性。

为什么不能是这样的:

<xsl:template match="subcategories"> 
    <ul> 
    <xsl:apply-templates select="item"/> 
    </ul> 
</xsl:template> 

<xsl:template match="item"> 
    <xsl:call-template name="categories-nav-entries"/> 
</xsl:template> 
+0

谢谢 - DRY'ed现在工作。似乎我需要添加一些额外的逻辑来处理空的“子类别”节点 - 我已经将新的XSLT添加到了我的问题中。 –