XSLT:父节点属性条件下的输出列表

时间:2011-08-22 14:06:04

标签: templates xslt attributes parent-child xbel

我很难创建一个列表,以便在父节点('folder')条件下显示,属性'folding'设置为'yes'或'no'。 结果将仅显示列表的前两个级别,而不是如下所示的第三个级别。

  • 第一。等级:显示
  • 第二。等级:显示
  • 第三。等级:不显示

我们的想法是使用<folder folded="yes">检查'folder'属性<xsl:if test="not(parent::yes)">。 这应该有资格获得第三名。等级没有被显示,但不知何故它没有做我想做的事情。 我可能使用了错误的构造和/或语法。 非常感谢帮助,谢谢。

包含一些内容的XML结构:

<xbel>
    <folder folded="yes">
        <level>1</level>
        <title>bookmarks</title>
        <desc>my bookmarks</desc>
        <folder folded="no">
            <level>2</level>
            <title>Android</title>
            <desc>my Android</desc>
            <bookmark href="http://www.phonesreview.co.uk/">
                <title>HTC Sync 3.0.5422 Update: Aria, Desire, Hero, Legend</title>
                <desc>The new HTC Sync 3.0.5422 update will be most welcome...</desc>
            </bookmark>
            <folder folded="no">
                <level>3</level>
                <title>Apps</title>
                <desc>Android Apps</desc>
                <bookmark href="http://www.androidzoom.com/">
                    <title>Android Communication Apps</title>
                    <desc>Download Communication Apps for Android.</desc>
                </bookmark>
                <bookmark href="http://www.htc.com/">
                    <title>HTC - Android</title>
                    <desc>Apps for HTC-Android.</desc>
                </bookmark>
            </folder>
        </folder>
    </folder>
</xbel>

XSLT:

 <!--creates a nested list of elements named 'folder'-->
<xsl:template match="folder" mode="linklist">
    <li>
        <xsl:if test="folder/level = 2">
                Level:<xsl:value-of select="level"/> / 
                Title:<xsl:value-of select="title"/> / 
                Desc:<xsl:value-of select="desc"/>
        <ul>
            <xsl:apply-templates mode="linklist" />
        </ul>
        </xsl:if>
    </li>
</xsl:template>

<xsl:template match="bookmark" mode="linklist">
    <li>  <!-- this bookmark is just another item in the list of bookmarks -->
        <!-- the title -->
            <a rel="nofollow" href="{@href}"><xsl:value-of select="title"/></a>
        <!-- the description -->
        <xsl:if test="desc">
            <span class="bookmarkDesc">
                <xsl:value-of select="desc"/>
            </span>
        </xsl:if>
    </li>
</xsl:template>

样式表HTML

<body>

<ul>
    <xsl:apply-templates mode="linklist" />
</ul>

</body>

生成的输出(级别:1-3)

Level:1 / Title:bookmarks / Desc:my bookmarks
        Level:2 / Title:Android / Desc:my Android
            HTC Sync 3.0.5422 Update: Aria, Desire, Hero, Legend ...
            Level:3 / Title:Apps / Desc:Android Apps
                Android Communication AppsDownload Communication Apps for Android.
                HTC - AndroidApps for HTC-Android.

预期输出:(等级:1-2)

Level:1 / Title:bookmarks / Desc:my bookmarks
        Level:2 / Title:Android / Desc:my Android
            HTC Sync 3.0.5422 Update: Aria, Desire, Hero, Legend ...

我尝试了这个模板,但输出了最后两个节点,我需要两个第一个节点。

<xsl:template match="folder[parent::folder/@folded = 'yes']" mode="linklist">

1 个答案:

答案 0 :(得分:1)

为防止处理展开的folder元素,您可以做的最简单的更改是添加一个吞下它们的空模板(即不产生输出):

<xsl:template match="folder[@folded='no']" mode="linklist"/>

将使用您现有的模板处理所有folderfolded属性不等于no的元素;那些新的将被捕获。

如果您希望处理每个folder元素,其自身的folded属性等于yes或其父元素(如更新的XML示例中所示),则使用以下模板:

<xsl:template match="folder[@folded='yes' or ../@folded='yes']" mode="linklist">
    <!-- body elided -->
</xsl:template>

您可能还想要包含一个空模板来隐藏所有其他folder元素:

<xsl:template match="folder" mode="linklist" />