在 xslt 1.0 中对嵌套元素进行分组 [英] Grouping nested elements in xslt 1.0

查看:42
本文介绍了在 xslt 1.0 中对嵌套元素进行分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在查看 XSLT 1.0 中 Muenchian 分组的示例,特别是这个示例 此处.但是我无法让它处理更复杂的 XML 结构.

我的 XML 目前看起来像这样:

但是,当它们具有相同的运动和事件时,我想将 Rank 节点分组到相同的 Ranks 父项下.所以我希望结果是这样的:

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

任何建议将不胜感激.

解决方案

这种转变:

<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:模板><xsl:template match="竞赛"><比赛><xsl:apply-templates/></比赛></xsl:模板><xsl:模板匹配=比赛[不(生成ID()=生成 id(key('kContestById', @sportId)[1]))]"/><xsl:template match="Ranks"><排名><xsl:apply-templates select="key('kContestById', ../@sportId)/Ranks/Rank"/></排名></xsl:模板></xsl:stylesheet>

应用于提供的 XML 文档时:

<比赛><比赛 SportId="35"><运动>沙滩排球</运动><活动>男士</活动><排名><Rank position="1" eventId="1"><运动员>运动员 1a/运动员 2a [德国]</运动员><结果>2</结果></排名><Rank position="2" eventId="1"><运动员>运动员 1b/运动员 2b [NED]</运动员><结果>0</结果></排名></排名></比赛><比赛 SportId="32"><体育>网球</体育><赛事>女子单打</赛事><排名><Rank position="1" eventId="2"><运动员>网球运动员1</运动员><结果>2</结果></排名><Rank position="2" eventId="2"><运动员>网球运动员2</运动员><结果>1</结果></排名></排名></比赛><比赛 SportId="35"><运动>沙滩排球</运动><活动>男士</活动><排名><Rank position="1" eventId="3"><运动员>运动员 3a/运动员 4a [AUT]</运动员><结果>2</结果></排名><Rank position="2" eventId="3"><运动员>运动员 3b/运动员 4b [SUI]</运动员><结果>0</结果></排名></排名></比赛></比赛></比赛结果>

产生想要的、正确的结果:

<比赛><比赛 SportId="35"><运动>沙滩排球</运动><活动>男士</活动><排名><Rank position="1" eventId="1"><运动员>运动员 1a/运动员 2a [德国]</运动员><结果>2</结果></排名><Rank position="2" eventId="1"><运动员>运动员 1b/运动员 2b [NED]</运动员><结果>0</结果></排名><Rank position="1" eventId="3"><运动员>运动员 3a/运动员 4a [AUT]</运动员><结果>2</结果></排名><Rank position="2" eventId="3"><运动员>运动员 3b/运动员 4b [SUI]</运动员><结果>0</结果></排名></排名></比赛><比赛 SportId="32"><体育>网球</体育><赛事>女子单打</赛事><排名><Rank position="1" eventId="2"><运动员>网球运动员1</运动员><结果>2</结果></排名><Rank position="2" eventId="2"><运动员>网球运动员2</运动员><结果>1</结果></排名></排名></比赛></比赛></比赛结果>

说明:

正确使用慕尼黑分组方法并覆盖身份规则.>

I've been looking at examples of Muenchian grouping in XSLT 1.0, specifically this example here. However I'm unable to get it working on a more complex XML structure.

My XML currently looks like this:

<?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>

However I want to group the Rank nodes under the same Ranks parent when they have the same Sport and Event. So I want the result to look like this:

<?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>

I'm just a little lost how to do this as the only other examples are dealing with a much simpler structure and I'm not sure if it's possible or how my key and templates need to be structured to do this. Can anyone provide some examples how this might be achieved?

Any advice would be appreciated.

解决方案

This transformation:

<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>

when applied on the provided XML document:

<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>

produces the wanted, correct result:

<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>

Explanation:

Proper use of the Muenchian grouping method and overriding the identity rule.

这篇关于在 xslt 1.0 中对嵌套元素进行分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆