加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

xml – 用于从平面树问题创建嵌套列表的XSL

发布时间:2020-12-16 23:22:56 所属栏目:百科 来源:网络整理
导读:我需要能够从平面树创建嵌套列表.例如,输入可能是这样的: root h1text/h1 list level="1"num1/list list level="1"num2/list list level="2"sub-num1/list list level="2"sub-num2/list list level="3"sub-sub-num1/list list level="1"num3/list ptext/p l
我需要能够从平面树创建嵌套列表.例如,输入可能是这样的:

<root>
    <h1>text</h1>
    <list level="1">num1</list>
    <list level="1">num2</list>
    <list level="2">sub-num1</list>
    <list level="2">sub-num2</list>
    <list level="3">sub-sub-num1</list>
    <list level="1">num3</list>
    <p>text</p>
    <list>num1</list>
    <list>num2</list>
    <h2>text</h2>
</root>

输出应嵌套如下:

<root>
<h1>text</h1>
    <ol>
        <li>num1</li>
        <li>num2
             <ol>
                <li>sub-num1</li>
                <li>sub-num2
                    <ol>
                        <li>sub-sub-num1</li>
                    </ol>
                </li>
            </ol>
        </li>
        <li>num3</li>
    </ol>
    <p>text</p>
    <ol>
        <li>num1</li>
        <li>num2</li>
    </ol>
    <h2>text</h2>
</root>

我尝试了一些方法,但似乎无法得到它.任何帮助是极大的赞赏.
注意:我需要使用XSLT 1.0来完成此操作.

解决方法

这种转变:

<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:key name="kListGroup" match="list"
  use="generate-id(
          preceding-sibling::node()[not(self::list)][1]
                   )"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()[1]|@*"/>
  </xsl:copy>
  <xsl:apply-templates select=
   "following-sibling::node()[1]"/>
 </xsl:template>

 <xsl:template match=
  "list[preceding-sibling::node()[1][not(self::list)]]">

  <ol>
    <xsl:apply-templates mode="listgroup" select=
     "key('kListGroup',generate-id(preceding-sibling::node()[1])
          )
          [not(@level) or @level = 1]
     "/>
  </ol>
  <xsl:apply-templates select=
   "following-sibling::node()[not(self::list)][1]"/>
 </xsl:template>

 <xsl:template match="list" mode="listgroup">
  <li>
    <xsl:value-of select="."/>

    <xsl:variable name="vNext" select=
     "following-sibling::list
            [not(@level > current()/@level)][1]
     |
      following-sibling::node()[not(self::list)][1]
     "/>

     <xsl:variable name="vNextLevel" select=
     "following-sibling::list
     [@level = current()/@level +1]
      [generate-id(following-sibling::list
            [not(@level > current()/@level)][1]
           |
             following-sibling::node()[not(self::list)][1]
                  )
      =
       generate-id($vNext)
      ]
     "/>

     <xsl:if test="$vNextLevel">
     <ol>
      <xsl:apply-templates mode="listgroup"
        select="$vNextLevel"/>
     </ol>
     </xsl:if>
  </li>
 </xsl:template>
</xsl:stylesheet>

当应用于此XML文档时(故意复杂以显示解决方案在许多边缘情况下工作):

<root>
    <h1>text</h1>
    <list level="1">1.1</list>
    <list level="1">1.2</list>
    <list level="2">1.2.1</list>
    <list level="2">1.2.2</list>
    <list level="3">1.2.2.1</list>
    <list level="1">1.3</list>
    <p>text</p>
    <list>2.1</list>
    <list>2.2</list>
    <h2>text</h2>
    <h1>text</h1>
    <list level="1">3.1</list>
    <list level="1">3.2</list>
    <list level="2">3.2.1</list>
    <list level="2">3.2.2</list>
    <list level="3">3.2.2.1</list>
    <list level="1">3.3</list>
    <list level="2">3.3.1</list>
    <list level="2">3.3.2</list>
    <p>text</p>
</root>

产生想要的,正确的结果:

<root>
   <h1>text</h1>
   <ol>
      <li>1.1</li>
      <li>1.2<ol>
            <li>1.2.1</li>
            <li>1.2.2<ol>
                  <li>1.2.2.1</li>
               </ol>
            </li>
         </ol>
      </li>
      <li>1.3</li>
   </ol>
   <p>text</p>
   <ol>
      <li>2.1</li>
      <li>2.2</li>
   </ol>
   <h2>text</h2>
   <h1>text</h1>
   <ol>
      <li>3.1</li>
      <li>3.2<ol>
            <li>3.2.1</li>
            <li>3.2.2<ol>
                  <li>3.2.2.1</li>
               </ol>
            </li>
         </ol>
      </li>
      <li>3.3<ol>
            <li>3.3.1</li>
            <li>3.3.2</li>
         </ol>
      </li>
   </ol>
   <p>text</p>
</root>

或者由浏览器显示:

???文本

???
??????> 1.1
??????> 1.2
????????????> 1.2.1
????????????> 1.2.2
??????????????????> 1.2.2.1
???????????????
????????????
?????????
??????
??????> 1.3
???

???文本

???
??????> 2.1
??????> 2.2
???

???文本

???文本

???
??????> 3.1
??????> 3.2
????????????> 3.2.1
????????????> 3.2.2
??????????????????> 3.2.2.1
???????????????
????????????
?????????
??????
??????> 3.3
????????????> 3.3.1
????????????> 3.3.2
?????????
??????
???

???文本

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读