XSLT嵌套列表项

时间:2011-08-28 17:11:00

标签: html xml xslt xpath

我是xslt的新手,我试图处理嵌套无序或有序列表项的情况  例如:

*  Dresses
          # Formal
                -  Men
                -  Women
                - Children
          # Casual
     *  FootWear
     *  Other Accessories

基本上,列表项是嵌套在其他项中的,但我们可以尽可能深地嵌套。你能给我一个关于如何实现这个目标的一般想法吗?

伊迪丝说:感谢您的快速回复。这是我的xml:

<?xml version="1.0" encoding="utf-8"?>
<emailmessage>
    <ul>
        <li>Dresses</li>
        <ul>
            <li>Professional</li>
            <ul>
                <li>Mens</li>
                <li>Womens</li>
            </ul>
            <li>Causual </li>
        </ul>
        <li>FootWear</li>
        <li>Other Accessories</li>
    </ul>
</emailmessage>

这是我的html类型的xml,格式是我想以纯文本形式获得的,即

  • 一个标签和*,如果其<li>没有任何祖先
  • 两个标签和#如果它的第一个子列表,即一个有一个祖先
  • 如果子列表的子列表有两个祖先,则带有-的三个选项卡。

格式重复..

* Dresses
    # Formal
        - Men
        - Women
        - Children
    # Casual
* FootWear
* Other Accessories

3 个答案:

答案 0 :(得分:3)

此转换适用于任何级别的嵌套,最多20个

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vIndent"
  select="'&#10;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;'"/>

 <xsl:template match="li">
  <xsl:value-of select=
   "concat(substring($vIndent,1, count(ancestor::ul)+1),.)"/>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档

<emailmessage>
    <ul>
        <li>* Dresses</li>
        <ul>
            <li># Professional</li>
            <ul>
                <li>- Mens</li>
                <li>- Womens</li>
            </ul>
            <li># Causual </li>
        </ul>
        <li>* FootWear</li>
        <li>* Other Accessories</li>
    </ul>
</emailmessage>

生成想要的正确结果

* Dresses
    # Professional
        - Mens
        - Womens
    # Causual 
* FootWear
* Other Accessories

更新 无限嵌套

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="li">
  <xsl:text>&#10;</xsl:text>
  <xsl:for-each select="ancestor::ul"><xsl:text>&#9;</xsl:text></xsl:for-each>
  <xsl:value-of select="."/>
 </xsl:template>
</xsl:stylesheet>

Update2 :OP已指出XML文档中不存在标记字符(*,*和 - )。以下是适用于无限嵌套的解决方案:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vDelims" select="'- * # '"/>

 <xsl:template match="li">
  <xsl:text>&#10;</xsl:text>
  <xsl:for-each select="ancestor::ul"><xsl:text>&#9;</xsl:text></xsl:for-each>
  <xsl:value-of select=
   "substring($vDelims,
              2*(1+count(ancestor::ul) mod 3) -1,
              2)"/>
  <xsl:value-of select="."/>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时(如上所示,但删除了子弹字符)

<emailmessage>
    <ul>
        <li>Dresses</li>
        <ul>
            <li>Professional</li>
            <ul>
                <li>Mens</li>
                <li>Womens</li>
            </ul>
            <li>Causual </li>
        </ul>
        <li>FootWear</li>
        <li>Other Accessories</li>
    </ul>
</emailmessage>

产生同样的,想要的和正确的结果

* Dresses
    # Professional
        - Mens
        - Womens
    # Causual 
* FootWear
* Other Accessories

答案 1 :(得分:2)

计算模板匹配时的 ul 祖先(注意第一个不需要它)。这个转换应该给你一个很好的起点:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="emailmessage/ul/li">
        <xsl:value-of select="concat('&#09;*',.,'&#xA;')"/>
    </xsl:template>

    <xsl:template match="li[count(ancestor::ul)=2]">
        <xsl:value-of select="concat('&#09;&#09;#',.,'&#xA;')"/>
    </xsl:template>

    <xsl:template match="li[count(ancestor::ul)=3]">
        <xsl:value-of select="concat('&#09;&#09;'&#09;-',.,'&#xA;')"/>
    </xsl:template>

</xsl:stylesheet>

产生

* Dresses
    # Professional
        - Mens
        - Womens
    # Causual 
* FootWear
* Other Accessories

答案 2 :(得分:0)

也许this example会有所帮助?它展示了如何使用XSLT为网站构建树导航。