【问题标题】:Grouping nested elements in xslt 1.0在 xslt 1.0 中对嵌套元素进行分组
【发布时间】:2012-08-02 10:27:22
【问题描述】:

我一直在研究 XSLT 1.0 中的 Muenchian 分组示例,特别是这个示例 here。但是我无法让它在更复杂的 XML 结构上工作。

我的 XML 当前如下所示:

<?xml version="1.0" encoding="utf-8"?>
<ContestResults>
  <Contests>
    <Contest sportId="35">
      <Sport>Beach Volleyball</Sport>
      <Event>Men's</Event>
      <Ranks>
        <Rank position="1" eventId="1">
          <Athlete>Athlete 1a / Athlete 2a [GER]</Athlete>
          <Result>2</Result>
        </Rank>
        <Rank position="2" eventId="1">
          <Athlete>Athlete 1b / Athlete 2b [NED]</Athlete>
          <Result>0</Result>
        </Rank>
      </Ranks>
    </Contest>
    <Contest sportId="32">
      <Sport>Tennis</Sport>
      <Event>Women's Singles</Event>
      <Ranks>
        <Rank position="1" eventId="2">
          <Athlete>Tennis Athlete 1</Athlete>
          <Result>2</Result>
        </Rank>
        <Rank position="2" eventId="2">
          <Athlete>Tennis Athlete 2</Athlete>
          <Result>1</Result>
        </Rank>
      </Ranks>
    </Contest>
    <Contest sportId="35">
      <Sport>Beach Volleyball</Sport>
      <Event>Men's</Event>
      <Ranks>
        <Rank position="1" eventId="3">
          <Athlete>Athlete 3a / Athlete 4a [AUT]</Athlete>
          <Result>2</Result>
        </Rank>
        <Rank position="2" eventId="3">
          <Athlete>Athlete 3b / Athlete 4b [SUI]</Athlete>
          <Result>0</Result>
        </Rank>
      </Ranks>
    </Contest>
    </Contests>
</ContestResults>

但是,当它们具有相同的 Sport 和 Event 时,我想将 Rank 节点分组到相同的 Ranks 父级下。所以我希望结果看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<ContestResults>
  <Contests>
    <Contest sportId="35">
      <Sport>Beach Volleyball</Sport>
      <Event>Men's</Event>
      <Ranks>
        <Rank position="1" eventId="1">
          <Athlete>Athlete 1a / Athlete 2a [GER]</Athlete>
          <Result>2</Result>
        </Rank>
        <Rank position="2" eventId="1">
          <Athlete>Athlete 1b / Athlete 2b [NED]</Athlete>
          <Result>0</Result>
        </Rank>
        <Rank position="1" eventId="3">
          <Athlete>Athlete 3a / Athlete 4a [AUT]</Athlete>
          <Result>2</Result>
        </Rank>
        <Rank position="2" eventId="3">
          <Athlete>Athlete 3b / Athlete 4b [SUI]</Athlete>
          <Result>0</Result>
        </Rank>
      </Ranks>
    </Contest>
    <Contest sportId="32">
      <Sport>Tennis</Sport>
      <Event>Women's Singles</Event>
      <Ranks>
        <Rank position="1" eventId="2">
          <Athlete>Tennis Athlete 1</Athlete>
          <Result>2</Result>
        </Rank>
        <Rank position="2" eventId="2">
          <Athlete>Tennis Athlete 2</Athlete>
          <Result>1</Result>
        </Rank>
      </Ranks>
    </Contest>
  </Contests>
</ContestResults>

我只是有点迷失如何做到这一点,因为唯一的其他例子是处理一个更简单的结构,我不确定这是否可能或者我的密钥和模板需要如何构建才能做到这一点。谁能提供一些示例如何实现?

任何建议将不胜感激。

【问题讨论】:

    标签: xslt-1.0 xslkey xsl-grouping


    【解决方案1】:

    这种转变

    <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="kContestById" match="Contest" use="@sportId"/>
    
     <xsl:template match="node()|@*">
         <xsl:copy>
           <xsl:apply-templates select="node()|@*"/>
         </xsl:copy>
     </xsl:template>
    
     <xsl:template match="Contests">
          <Contests>
           <xsl:apply-templates/>
          </Contests>
     </xsl:template>
    
     <xsl:template match=
      "Contest
        [not(generate-id()
        =
         generate-id(key('kContestById', @sportId)[1]))
         ]"/>
     <xsl:template match="Ranks">
      <Ranks>
        <xsl:apply-templates select="key('kContestById', ../@sportId)/Ranks/Rank"/>
      </Ranks>
     </xsl:template>
    </xsl:stylesheet>
    

    应用于提供的 XML 文档时:

    <ContestResults>
      <Contests>
        <Contest sportId="35">
          <Sport>Beach Volleyball</Sport>
          <Event>Men's</Event>
          <Ranks>
            <Rank position="1" eventId="1">
              <Athlete>Athlete 1a / Athlete 2a [GER]</Athlete>
              <Result>2</Result>
            </Rank>
            <Rank position="2" eventId="1">
              <Athlete>Athlete 1b / Athlete 2b [NED]</Athlete>
              <Result>0</Result>
            </Rank>
          </Ranks>
        </Contest>
        <Contest sportId="32">
          <Sport>Tennis</Sport>
          <Event>Women's Singles</Event>
          <Ranks>
            <Rank position="1" eventId="2">
              <Athlete>Tennis Athlete 1</Athlete>
              <Result>2</Result>
            </Rank>
            <Rank position="2" eventId="2">
              <Athlete>Tennis Athlete 2</Athlete>
              <Result>1</Result>
            </Rank>
          </Ranks>
        </Contest>
        <Contest sportId="35">
          <Sport>Beach Volleyball</Sport>
          <Event>Men's</Event>
          <Ranks>
            <Rank position="1" eventId="3">
              <Athlete>Athlete 3a / Athlete 4a [AUT]</Athlete>
              <Result>2</Result>
            </Rank>
            <Rank position="2" eventId="3">
              <Athlete>Athlete 3b / Athlete 4b [SUI]</Athlete>
              <Result>0</Result>
            </Rank>
          </Ranks>
        </Contest>
        </Contests>
    </ContestResults>
    

    产生想要的正确结果:

    <ContestResults>
       <Contests>
          <Contest sportId="35">
             <Sport>Beach Volleyball</Sport>
             <Event>Men's</Event>
             <Ranks>
                <Rank position="1" eventId="1">
                   <Athlete>Athlete 1a / Athlete 2a [GER]</Athlete>
                   <Result>2</Result>
                </Rank>
                <Rank position="2" eventId="1">
                   <Athlete>Athlete 1b / Athlete 2b [NED]</Athlete>
                   <Result>0</Result>
                </Rank>
                <Rank position="1" eventId="3">
                   <Athlete>Athlete 3a / Athlete 4a [AUT]</Athlete>
                   <Result>2</Result>
                </Rank>
                <Rank position="2" eventId="3">
                   <Athlete>Athlete 3b / Athlete 4b [SUI]</Athlete>
                   <Result>0</Result>
                </Rank>
             </Ranks>
          </Contest>
          <Contest sportId="32">
             <Sport>Tennis</Sport>
             <Event>Women's Singles</Event>
             <Ranks>
                <Rank position="1" eventId="2">
                   <Athlete>Tennis Athlete 1</Athlete>
                   <Result>2</Result>
                </Rank>
                <Rank position="2" eventId="2">
                   <Athlete>Tennis Athlete 2</Athlete>
                   <Result>1</Result>
                </Rank>
             </Ranks>
          </Contest>
       </Contests>
    </ContestResults>
    

    说明

    正确使用 Muenchian grouping method 并覆盖 identity rule

    【讨论】:

    • 感谢您的帮助。效果很好,尽管我需要更新我的密钥以使用 Sport AND Event 以确保我没有将错误的事件组合在一起,即 concat(Sport, '+', Event)
    • @pat007:不客气。至于不使用复合键进行分组,提供的 XML 文档和想要的结果没有暗示这是必需的——如果是这样的话——当然,这很容易做到。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    • 2014-11-16
    • 2011-07-01
    • 1970-01-01
    相关资源
    最近更新 更多