Динамическое группирование узлов XSLT с помощью преобразования - PullRequest
1 голос
/ 21 апреля 2010

Я пытаюсь создать такую ​​страницу с помощью преобразования XSLT.

Страницы

  • стр.1
  • стр.2

Ссылки

  • link1
  • link2

Вот это 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.

Ответы [ 3 ]

4 голосов
/ 21 апреля 2010

Итак, вы хотите сгруппировать по имени узла.Не самая лучшая идея для хранения в узлах 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>
1 голос
/ 21 апреля 2010

Я бы начал с

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

и продолжайте оттуда.

1 голос
/ 21 апреля 2010

Вы selecting все (*).

Используйте select="Pages" для выбора страниц и select="Links" для ссылок.

Узнайте о выражениях XPath здесь.

...