【问题标题】:How "to fold recursively by a tag" a group of selected (neighbor) tags with XSLT1?如何使用 XSLT1“通过标签递归折叠”一组选定的(邻居)标签?
【发布时间】:2013-08-19 11:44:57
【问题描述】:

我在this other one 评论了当前的问题:现在更复杂,因为需要重复。举例说明:

  <root>
    <c>cccc</c>
    <a gr="g1_1">aaaa</a>    <b gr="g1_1">1111</b>
    <a gr="g2_1" into="g1_1">bbbb</a>   <b gr="g2_1" into="g1_1">56565</b>
    <a gr="g3_1" into="g2_1">BB</a>   <b gr="g3_1" into="g2_1">55</b>
    <a gr="g1_2">xxxx</a>    <b gr="g1_2">2222</b>
    <a gr="g2_2" into="g1_2">wwww</a>   <b gr="g2_2" into="g1_2">3433</b>
  </root>

必须用 fold 标记括起来,结果(在 XSLT 之后)为:

  <root>
    <c>cccc</c>

    <fold>
      <a gr="g1_1">aaaa</a>    <b gr="g1_1">1111</b>
      <fold><a gr="g2_1" into="g1_1">bbbb</a>   
            <b gr="g2_1" into="g1_1">56565</b>
            <fold><a gr="g3_1" into="g2_1">BB</a>   
                  <b gr="g3_1" into="g2_1">55</b>
            </fold>
       </fold>
    </fold>

    <fold>
      <a gr="g1_2">xxxx</a>    <b gr="g1_2">2222</b>
      <fold><a gr="g2_2" into="g1_2">wwww</a>   
            <b gr="g2_2" into="g1_2">3433</b>
      </fold>
    </fold>
  </root>

注意事项

该示例有一个“分组标签”(@gr)和一个“超级分组”标签(@into 指向父组)。

@gr 是唯一组的 ID,也表示“折叠级别”,语法为 "g" level "_" level-id,因此,如果需要我们可以为折叠级别添加显式属性...或者可以添加和辅助结构(gdef 作为输入元数据),

 <gdef>
  <group gr="g1_1" level="1" into=""/>
  <group gr="g2_1" level="2" into="g1_1"/>
  <group gr="g3_1" level="3" into="g2_1"/>
  <group gr="g1_2" level="1" into=""/>
  <group gr="g2_2" level="2" into="1_2"/>
 </gdef>

等等

【问题讨论】:

    标签: recursion xslt-1.0 fold


    【解决方案1】:

    你不需要递归。您只需要小心地将模板应用于兄弟姐妹。
    下面的代码改编自您的其他(推荐)问题中的解决方案。

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      <xsl:strip-space elements="*" />
      <xsl:output indent="yes" />
      <xsl:key name="key" match="*[@gr]" use="@gr" />
    
      <xsl:template match="*[*/@gr]">
        <xsl:copy>
          <xsl:apply-templates select="*[not(@into)]"/><!--start by most top-level ones-->
        </xsl:copy>
      </xsl:template>
      <xsl:template match="*[@gr]"/>
      <xsl:template match="*[@gr][generate-id() = generate-id(key('key', @gr)[1])]">
        <fold>
          <xsl:for-each select="key('key', @gr)">
            <xsl:call-template name="identity" />
          </xsl:for-each>
          <xsl:apply-templates select="following-sibling::*[@into = current()/@gr]"/>
        </fold>
      </xsl:template>
      <xsl:template match="node()|@*" name="identity" >
        <xsl:copy>
          <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
      </xsl:template>
    </xsl:stylesheet>
    

    【讨论】:

    • 操作,好惊喜,谢谢!这个周末我会检查你的解决方案。
    • PS:你的代码递归在xsl:call-template name="identity"。 :)
    猜你喜欢
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    • 2014-02-25
    • 1970-01-01
    • 1970-01-01
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多