【问题标题】:Grouping XSLT nodes via transformation dynamically通过转换动态分组 XSLT 节点
【发布时间】:2011-02-10 15:51:08
【问题描述】:

我正在尝试通过 XSLT 转换创建这样的页面。

页面

  • 第1页
  • 第2页

链接

  • 链接1
  • 链接2

这里是xml

<siteMenu>
  <Pages>
    <title>page1</title>
  </Pages>
  <Pages>
    <title>page2</title>
  </Pages>
  <Links>
    <title>link1</title>
  </Links>
  <Links>
    <title>link2</title>
  </Links>
</siteMenu>

我尝试过使用

<xsl:for-each select="*"> and <xsl:for-each-group select="*" group-by="@v">

但这给了我每个元素,但是我如何根据父节点将它们分开?

我还想让它动态化,这样如果我在 siteMenu 中添加另一个项目,它会适当地更新 xslt。

【问题讨论】:

    标签: xslt transform foreach


    【解决方案1】:

    所以你想按节点名称分组。在 XML 节点中存储比实际 结构信息 更多的信息并不是最好的主意,但你可以这样做:

    <siteMenu>
      <Pages>
        <title>page1</title>
      </Pages>
      <Pages>
        <title>page2</title>
      </Pages>
      <Links>
        <title>link1</title>
      </Links>
      <Links>
        <title>link2</title>
      </Links>
      <Sites>
        <title>site1</title>
      </Sites>
      <Sites>
        <title>site2</title>
      </Sites>
    </siteMenu>
    

    还有这个 XSLT 2.0 转换(仅相关片段):

    <xsl:template match="siteMenu">
      <xsl:for-each-group select="*" group-by="name()">
        <xsl:sort select="name()" />
        <div>
          <h1><xsl:value-of-select="current-grouping-key()" /></h1>
          <ul>
            <xsl:for-each select="current-group()">
              <li><xsl:value-of select="title" /></li>
            </xsl:for-each>
          </ul>
        </div>
      </xsl:for-each-group>
    </xsl:template>
    

    或此 XSLT 1.0 转换(仅相关片段):

    <xsl:key name="kMenu" match="siteMenu/*" use="name()" />
    
    <xsl:template match="siteMenu">
      <xsl:for-each select="*[
        generate-id() = generate-id(key('kMenu', name())[1])
      ]">
        <xsl:sort select="name()" />
        <div>
          <h1><xsl:value-of-select="name()" /></h1>
          <ul>
            <xsl:for-each select="key('kMenu', name())">
              <li><xsl:value-of select="title" /></li>
            </xsl:for-each>
          </ul>
        </div>
      </xsl:for-each-group>
    </xsl:template>
    

    提示:您可能想考虑使用这样的 XML,这显然更符合您的站点结构,并且您不需要分组即可正确输出。

    <siteMenu>
      <section name="Pages">
        <title>page1</title>
        <title>page2</title>
      </section>
      <section name="Links">
        <title>link1</title>
        <title>link2</title>
      </section>
      <section name="Sites">
        <title>site1</title>
        <title>site2</title>
      </section>
    </siteMenu>
    

    【讨论】:

    • 这适用于 XSLT 2.0,但不适用于 1.0。那我得另寻路了。
    • @scott:但是您自己在问题中使用了for-each-group,并没有留下任何迹象表明您使用的是 XSLT 1.0。我只是不得不假设您使用的是 2.0... 将添加 XSLT 1.0 解决方案。
    • 我找到了一个理想的解决方案,jenitennison.com/xslt/grouping/muenchian.html。效果很好。
    • @scott:这个答案的作用 Muenchian grouping。
    【解决方案2】:

    你是 selecting 一切 (*)。

    使用select="Pages" 选择页面,使用select="Links" 选择链接。

    了解 XPath 表达式here

    【讨论】:

    • 问题是我想让它动态化。这样我就可以添加另一个名为“站点”的节点并将其添加到菜单中。
    【解决方案3】:

    我会开始

    <ul>
      <xsl:for-each select="//Pages">
        <li><xsl:value-of select="./title"/></li>
      </xsl:for-each>
    </ul>
    

    然后从那里继续。

    【讨论】:

    • 查看我对 Oded 的回复,了解如何使其动态化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    • 2014-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多