Xml XSLT将重复属性之间的同级元素分组

Xml XSLT将重复属性之间的同级元素分组,xml,xslt,Xml,Xslt,我已经绞尽脑汁好几天了,我一辈子都想不出如何做到这一点。以以下XML为例: <Root> <container> <widget type="nav"> <links> <tab type="label" header="Top Level Tab1"/> <tab type="page" header="submenu

我已经绞尽脑汁好几天了,我一辈子都想不出如何做到这一点。以以下XML为例:

<Root>
   <container>
        <widget type="nav">
            <links>
                <tab type="label" header="Top Level Tab1"/>
                <tab type="page" header="submenu of tab1"/>
                <tab type="page" header="submenu of tab1"/>
                <tab type="page" header="submenu of tab1"/>
                <tab type="label" header="Top Level Tab2"/>
                <tab type="page" header="submenu of tab2"/>
                <tab type="page" header="submenu of tab2"/>
                <tab type="page" header="submenu of tab2"/>
                <tab type="page" header="submenu of tab2"/>
                <tab type="page" header="submenu of tab2"/>
                <tab type="label" header="Top Level Tab3"/>
                <tab type="page" header="submenu of tab3"/>
                <tab type="page" header="submenu of tab3"/>
                <tab type="page" header="submenu of tab3"/>
                <tab type="page" header="submenu of tab3"/>
                <tab type="page" header="submenu of tab3"/>
            </links>
        </widget>
   </container>
</root>

我需要做的是将其转换为一个导航区域,在每个选项卡上用“标签”类型分开,并将以下同级项放在下面。比如说

<ul>
    <li>
        <a href="link for label">Top Level Header1</a>
        <div class="submenu">
            <ul>
                <li>Submenu Link 1</li>
                <li>Submenu Link 1</li>
                <li>Submenu Link 1</li>
            </ul>
        </div>
    </li>
    <li>
        <a href="link for label">Top Level Header2</a>
        <div class="submenu">
            <ul>
                <li>Submenu Link 2</li>
                <li>Submenu Link 2</li>
                <li>Submenu Link 2</li>
            </ul>
        </div>
    </li>
    <li>
        <a href="link for label">Top Level Header3</a>
        <div class="submenu">
            <ul>
                <li>Submenu Link 3</li>
                <li>Submenu Link 3</li>
                <li>Submenu Link 3</li>
            </ul>
        </div>
    </li>
</ul>
    • 子菜单链接1
    • 子菜单链接1
    • 子菜单链接1
    • 子菜单链接2
    • 子菜单链接2
    • 子菜单链接2
    • 子菜单链接3
    • 子菜单链接3
    • 子菜单链接3

任何指导都是值得赞赏的

因为XPath允许您选择具有相应轴的以下或前面的同级元素。为了提高效率,您可以使用钥匙:

<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:key name="subs" match="widget[@type = 'nav']/links/tab[@type = 'page']"
  use="generate-id(preceding-sibling::tab[@type = 'label'][1])"/>

<xsl:output method="html" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="container/widget[@type = 'nav']">
  <ul>
    <xsl:apply-templates select="links/tab[@type = 'label' and starts-with(@header, 'Top Level')]"/>
  </ul>
</xsl:template>

<xsl:template match="links/tab[@type = 'label' and starts-with(@header, 'Top Level')]">
  <li>
    <a href="link for label">
      <xsl:value-of select="@header"/>
    </a>
    <div class="submenu">
      <ul>
        <xsl:apply-templates select="key('subs', generate-id())"/>
      </ul>
    </div>
  </li>
</xsl:template>

<xsl:template match="links/tab[@type = 'page']">
  <li>
    <xsl:value-of select="@header"/>
  </li>
</xsl:template>

</xsl:stylesheet>

  • 样式表可以转换

    <Root>
       <container>
            <widget type="nav">
                <links>
                    <tab type="label" header="Top Level Tab1"/>
                    <tab type="page" header="submenu of tab1"/>
                    <tab type="page" header="submenu of tab1"/>
                    <tab type="page" header="submenu of tab1"/>
                    <tab type="label" header="Top Level Tab2"/>
                    <tab type="page" header="submenu of tab2"/>
                    <tab type="page" header="submenu of tab2"/>
                    <tab type="page" header="submenu of tab2"/>
                    <tab type="page" header="submenu of tab2"/>
                    <tab type="page" header="submenu of tab2"/>
                    <tab type="label" header="Top Level Tab3"/>
                    <tab type="page" header="submenu of tab3"/>
                    <tab type="page" header="submenu of tab3"/>
                    <tab type="page" header="submenu of tab3"/>
                    <tab type="page" header="submenu of tab3"/>
                    <tab type="page" header="submenu of tab3"/>
                </links>
            </widget>
       </container>
    </Root>
    
    
    
    进入

      • tab1的子菜单
      • tab1的子菜单
      • tab1的子菜单
      • tab2的子菜单
      • tab2的子菜单
      • tab2的子菜单
      • tab2的子菜单
      • tab2的子菜单
      • tab3的子菜单
      • tab3的子菜单
      • tab3的子菜单
      • tab3的子菜单
      • tab3的子菜单

    非常感谢您的支持,我必须修改一点以适应真正的样式表含义,但这与我所需要的完全一致!非常感谢。
    <ul>
       <li><a href="link for label">Top Level Tab1</a><div class="submenu">
             <ul>
                <li>submenu of tab1</li>
                <li>submenu of tab1</li>
                <li>submenu of tab1</li>
             </ul>
          </div>
       </li>
       <li><a href="link for label">Top Level Tab2</a><div class="submenu">
             <ul>
                <li>submenu of tab2</li>
                <li>submenu of tab2</li>
                <li>submenu of tab2</li>
                <li>submenu of tab2</li>
                <li>submenu of tab2</li>
             </ul>
          </div>
       </li>
       <li><a href="link for label">Top Level Tab3</a><div class="submenu">
             <ul>
                <li>submenu of tab3</li>
                <li>submenu of tab3</li>
                <li>submenu of tab3</li>
                <li>submenu of tab3</li>
                <li>submenu of tab3</li>
             </ul>
          </div>
       </li>
    </ul>