XSLT - 分为2级

时间:2013-05-06 18:59:40

标签: xslt group-by

希望你做得很好 我有一个场景,我从一个扁平结构的服务中获得结果集 此结果集包含Manager,他在每个项目中的项目和活动

我想将这个扁平结构转换为

的xml
Grouped by Manager
    Grouped by Project
         Activities in that Project

这是我的xml

<Results>
<Result>
    <ActivityId>101</ActivityId>
    <ActivityName>T1</ActivityName>
    <ProjectId>1001</ProjectId>
    <ProjectName>Prj1</ProjectName>
    <Description>some desc</Description>
    <manager>jcooper</manager>
</Result>
<Result>
    <ActivityId>102</ActivityId>
    <ActivityName>T2</ActivityName>
    <ProjectId>1002</ProjectId>
    <ProjectName>Prj2</ProjectName>
    <Description>some desc</Description>
    <manager>jstein</manager>
</Result>
<Result>
    <ActivityId>103</ActivityId>
    <ActivityName>T3</ActivityName>
    <ProjectId>1001</ProjectId>
    <ProjectName>Prj1</ProjectName>
    <Description>some desc</Description>
    <manager>jcooper</manager>
</Result>
<Result>
    <ActivityId>104</ActivityId>
    <ActivityName>T4</ActivityName>
    <ProjectId>1002</ProjectId>
    <ProjectName>Prj2</ProjectName>
    <Description>some desc</Description>
    <manager>jcooper</manager>
</Result>
<Result>
    <ActivityId>105</ActivityId>
    <ActivityName>T5</ActivityName>
    <ProjectId>1002</ProjectId>
    <ProjectName>Prj2</ProjectName>
    <Description>some desc</Description>
    <manager>jstein</manager>
</Result>
</Results>

在此, 经理jcooper有Prj1 {有活动T1,T3}和Prj2 {有活动T4} 经理jstein有Prj1(有活动T2)和prj2 {有活动T5}

这是我正在尝试的格式

Manager
    List of Prjs
        List of Activities in corresponding Project

<Results>
    <ManagerWiseResult>
        <Manager>jcooper</Manager>
        <Project>
            <ProjectId>1001</ProjectId>
            <ProjectName>Prj1</ProjectName>
            <Activities> <!--Activities in Project1 -->
                <IndActivity>
                    <ActivityId>101</ActivityId>
                    <ActivityName>T1</ActivityName>
                </IndActivity>
                <IndActivity>
                    <ActivityId>103</ActivityId>
                    <ActivityName>T2</ActivityName>
                </IndActivity>
            </Activities>
        </Project>
        <Project>
            <ProjectId>1002</ProjectId>
            <ProjectName>Prj2</ProjectName>
            <Activities>
                <IndActivity>
                    <ActivityId>104</ActivityId>
                    <ActivityName>T4</ActivityName>
                </IndActivity>
            </Activities>
        </Project>
    </ManagerWiseResult>
    <ManagerWiseResult>
        <Project>
            <ProjectId>1001</ProjectId>
            <ProjectName>Prj1</ProjectName>
            <Activities>
                <IndActivity>
                    <ActivityId>102</ActivityId>
                    <ActivityName>T2</ActivityName>
                </IndActivity>
            </Activities>
        </Project>
        <Project>
            <ProjectId>1002</ProjectId>
            <ProjectName>Prj2</ProjectName>
            <Activities>
                <IndActivity>
                    <ActivityId>105</ActivityId>
                    <ActivityName>T5</ActivityName>
                </IndActivity>
            </Activities>
        </Project>
    </ManagerWiseResult>
</Results>

我正试图找出解决方案,但不能。 专家,请你在这方面帮助我。

先谢谢, 拉维

2 个答案:

答案 0 :(得分:0)

此处的解决方案基于“Muenchian分组”

试试这个:

<xsl:stylesheet  version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" />

    <xsl:key name="kmanager" match="Result" use="manager" />
    <xsl:key name="kmanager_prj" match="Result" use="concat(manager,'#',ProjectId )" />

    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Result">
        <IndActivity>
            <xsl:apply-templates select="ActivityId" />
            <xsl:apply-templates select="ActivityName" />
        </IndActivity>
    </xsl:template>

    <xsl:template match="Result" mode="project">
        <Project>
            <xsl:copy-of select="ProjectId"/>
            <xsl:copy-of select="ProjectName"/>

            <Activities>
                <xsl:for-each select="key( 'kmanager_prj', concat(manager,'#',ProjectId ))">    
                    <xsl:apply-templates  select="."/>
                </xsl:for-each>
            </Activities>

        </Project>
    </xsl:template>


        <xsl:template match="Result" mode="manager">
        <xsl:apply-templates select="customer | jobType" />
            <ManagerWiseResult>
                <Manager>
                    <xsl:value-of select="manager"/>
                </Manager>
                <xsl:apply-templates mode="project"
            select="//Result[
                generate-id()= 
                generate-id(
                    key( 'kmanager_prj',
                            concat (current()/manager,'#', ProjectId )
                        ) [1])]"  />            
            </ManagerWiseResult>
    </xsl:template>
    <xsl:template match="/*">
        <xsl:copy>
        <xsl:apply-templates  mode="manager"
        select="//Result[
                generate-id()= 
                generate-id(
                    key( 'kmanager',
                            manager 
                        ) [1])]"  />
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

将生成此输出:

<?xml version="1.0"?>
<Results>
    <ManagerWiseResult>
        <Manager>jcooper</Manager>
        <Project>
            <ProjectId>1001</ProjectId>
            <ProjectName>Prj1</ProjectName>
            <Activities>
                <IndActivity>
                    <ActivityId>101</ActivityId>
                    <ActivityName>T1</ActivityName>
                </IndActivity>
                <IndActivity>
                    <ActivityId>103</ActivityId>
                    <ActivityName>T3</ActivityName>
                </IndActivity>
            </Activities>
        </Project>
        <Project>
            <ProjectId>1002</ProjectId>
            <ProjectName>Prj2</ProjectName>
            <Activities>
                <IndActivity>
                    <ActivityId>104</ActivityId>
                    <ActivityName>T4</ActivityName>
                </IndActivity>
            </Activities>
        </Project>
    </ManagerWiseResult>
    <ManagerWiseResult>
        <Manager>jstein</Manager>
        <Project>
            <ProjectId>1002</ProjectId>
            <ProjectName>Prj2</ProjectName>
            <Activities>
                <IndActivity>
                    <ActivityId>102</ActivityId>
                    <ActivityName>T2</ActivityName>
                </IndActivity>
                <IndActivity>
                    <ActivityId>105</ActivityId>
                    <ActivityName>T5</ActivityName>
                </IndActivity>
            </Activities>
        </Project>
    </ManagerWiseResult>
</Results>

注意:但这与你的陈述不符:

在此,经理jcooper有Prj1 {有活动T1,T3}和Prj2 {有活动T4}经理jstein有Prj1(有活动T2)和prj2 {有活动T5} < / p>

答案 1 :(得分:0)

这是一种可能的XSLT 2.0解决方案。

当这个XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
   <xsl:output omit-xml-declaration="yes" indent="yes"/>
   <xsl:strip-space elements="*"/>

   <xsl:key name="kResultByManager" match="Result" use="manager"/>

   <xsl:template match="/*">
     <Results>
       <xsl:for-each-group
         select="*/manager"
         group-by=".">
         <ManagerWiseResult>
           <Manager>
             <xsl:value-of select="."/>
           </Manager>
           <xsl:for-each-group
             select="key('kResultByManager', current-grouping-key())"
             group-by="ProjectId">
             <Project>
               <xsl:copy-of select="ProjectId|ProjectName"/>
                 <Activities>
                   <xsl:for-each select="current-group()">
                     <IndActivity>
                       <xsl:copy-of select="ActivityId|ActivityName"/>
                     </IndActivity>
                   </xsl:for-each>
                 </Activities>
               </Project>
             </xsl:for-each-group>
           </ManagerWiseResult>
         </xsl:for-each-group>
       </Results>
       </xsl:template>
</xsl:stylesheet>

...适用于提供的XML:

<?xml version="1.0" encoding="UTF-8"?>
<Results>
  <Result>
    <ActivityId>101</ActivityId>
    <ActivityName>T1</ActivityName>
    <ProjectId>1001</ProjectId>
    <ProjectName>Prj1</ProjectName>
    <Description>some desc</Description>
    <manager>jcooper</manager>
  </Result>
  <Result>
    <ActivityId>102</ActivityId>
    <ActivityName>T2</ActivityName>
    <ProjectId>1002</ProjectId>
    <ProjectName>Prj2</ProjectName>
    <Description>some desc</Description>
    <manager>jstein</manager>
  </Result>
  <Result>
    <ActivityId>103</ActivityId>
    <ActivityName>T3</ActivityName>
    <ProjectId>1001</ProjectId>
    <ProjectName>Prj1</ProjectName>
    <Description>some desc</Description>
    <manager>jcooper</manager>
  </Result>
  <Result>
    <ActivityId>104</ActivityId>
    <ActivityName>T4</ActivityName>
    <ProjectId>1002</ProjectId>
    <ProjectName>Prj2</ProjectName>
    <Description>some desc</Description>
    <manager>jcooper</manager>
  </Result>
  <Result>
    <ActivityId>105</ActivityId>
    <ActivityName>T5</ActivityName>
    <ProjectId>1002</ProjectId>
    <ProjectName>Prj2</ProjectName>
    <Description>some desc</Description>
    <manager>jstein</manager>
  </Result>
</Results>

...生成了想要的结果:

<Results>
  <ManagerWiseResult>
    <Manager>jcooper</Manager>
    <Project>
      <ProjectId>1001</ProjectId>
      <ProjectName>Prj1</ProjectName>
      <Activities>
        <IndActivity>
          <ActivityId>101</ActivityId>
          <ActivityName>T1</ActivityName>
        </IndActivity>
        <IndActivity>
          <ActivityId>103</ActivityId>
          <ActivityName>T3</ActivityName>
        </IndActivity>
      </Activities>
    </Project>
    <Project>
      <ProjectId>1002</ProjectId>
      <ProjectName>Prj2</ProjectName>
      <Activities>
        <IndActivity>
          <ActivityId>104</ActivityId>
          <ActivityName>T4</ActivityName>
        </IndActivity>
      </Activities>
    </Project>
  </ManagerWiseResult>
  <ManagerWiseResult>
    <Manager>jstein</Manager>
    <Project>
      <ProjectId>1002</ProjectId>
      <ProjectName>Prj2</ProjectName>
      <Activities>
        <IndActivity>
          <ActivityId>102</ActivityId>
          <ActivityName>T2</ActivityName>
        </IndActivity>
        <IndActivity>
          <ActivityId>105</ActivityId>
          <ActivityName>T5</ActivityName>
        </IndActivity>
      </Activities>
    </Project>
  </ManagerWiseResult>
</Results>