简体   繁体   中英

How to do multiple grouping in XSLT1.0

I have got below XSLT which working for single grouping, however I need to have multiple grouping for my xml below:

XSLT1.0:

<?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:variable name="linkURL" select="'/system/ASPX/Link.aspx?ID='"/>
  <xsl:template match="*">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates select="node()"/>
      <xsl:if test="self::navigation">
        <node GroupTitle="{//@GroupTitle[1]}" GroupCode="{//@GroupCode[1]}" url="{$linkURL}{//@GroupID[1]}">
          <nodes>
            <xsl:apply-templates select="node()" mode="group"></xsl:apply-templates>
          </nodes>
        </node>        
      </xsl:if>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*[normalize-space(@GroupCode) and not(*[not(normalize-space(@GroupCode))])]"/>

  <xsl:template match="node[normalize-space(@GroupCode)]" mode="group">
    <xsl:copy>    
      <xsl:apply-templates select="@*" mode="group"/>   
      <xsl:apply-templates select="node()" mode="group"/>      
    </xsl:copy>
  </xsl:template>

  <xsl:template match="node" mode="group">     
    <xsl:apply-templates select="node()" mode="group"/>
  </xsl:template>

  <xsl:template match="*" mode="group"/>

  <xsl:template  match="@*" mode="group">
    <xsl:attribute name="{name()}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>
  <!-- node attributes to be deleted have an empty template each -->
  <xsl:template match="@GroupTitle" mode="group"/>
  <xsl:template match="@GroupCode" mode="group"/>
  <xsl:template match="@GroupID" mode="group"/>
</xsl:stylesheet>

Part of XML:

<?xml version="1.0" encoding="utf-16"?>
<navigation path="/english">
    <resources>
        <Copyright>© 2011 mysite. All Rights Reserved.</Copyright>
    </resources>
    <node title="Root" id="tcm:233-38288-4" url="/">
        <node title="030. Plan &amp;amp; Book" id="tcm:233-38446-4" url="/plan_book/plan_and_book.aspx" indexpage="tcm:233-192249-64" compTitle="mysite Online Booking and Planning" imageSrcOn="/Preview/mysiteglobal/english/images/plan_book_highlight_tcm233-343461.gif" imageSrcOff="/Preview/mysiteglobal/english/images/plan_book_tcm233-343460.gif" imageSrcSelected="/Preview/mysiteglobal/english/images/plan_book_active_tcm233-343462.gif" imageSrcSelectedOn="/Preview/mysiteglobal/english/images/plan_book_highlight_tcm233-343461.gif" accessKey="P" GroupTitle="Plan and Book" GroupCode="PB" GroupID="tcm:234-458296">
            <node title="010. Search for a Flight" id="tcm:233-38911-4" url="/IBE.aspx" linktype="ibe" compTitle="Make a Booking" linksection="IBE" accessKey="1"/>
        </node> 
        <node title="035. Business Rewards" id="tcm:233-58061-4" url="/business_rewards/business_rewards.aspx" indexpage="tcm:233-358352-64" compTitle="Business Rewards" imageSrcOn="/Preview/mysiteglobal/english/images/business_rewards_highlight_tcm233-324549.gif" imageSrcOff="/Preview/mysiteglobal/english/images/business_rewards_tcm233-324548.gif" imageSrcSelected="/Preview/mysiteglobal/english/images/business_rewards_active_tcm233-324551.gif" imageSrcSelectedOn="/Preview/mysiteglobal/english/images/business_rewards_highlight_tcm233-324549.gif" authentication="sme-guest" GroupTitle="Skywards and Business Rewards" GroupCode="SB" GroupID="tcm:233-358296">
        </node> 
        <node title="040. Skywards" id="tcm:233-38448-4" url="/Skywards/skywards.aspx" indexpage="tcm:233-192262-64" compTitle="Skywards" imageSrcOn="/Preview/mysiteglobal/english/images/skywards_highlight_tcm233-343464.gif" imageSrcOff="/Preview/mysiteglobal/english/images/skywards_tcm233-343463.gif" imageSrcSelected="/Preview/mysiteglobal/english/images/skywards_active_tcm233-343465.gif" imageSrcSelectedOn="/Preview/mysiteglobal/english/images/skywards_highlight_tcm233-343464.gif" accessKey="S" GroupTitle="Skywards and Business Rewards" GroupCode="SB" GroupID="tcm:233-358296">
            <node title="080. The mysite High Street" id="tcm:233-59871-4" url="/Skywards/the_mysite_high_street/the_mysite_high_street.aspx" indexpage="tcm:233-346057-64" compTitle="The mysite High Street"/>
            <node title="090. Log In" id="tcm:233-92637-4" url="https://www.skywards.com/index.aspx" indexpage="tcm:233-636665-64" linktype="external" compTitle="Log In"/>
            <node title="100. Login" id="tcm:233-93287-4" url="/Skywards/skywardLogin/" GroupTitle="Skywards and Business Rewards" GroupCode="SB" GroupID="tcm:233-358296"/>
            <node title="110. Logout" id="tcm:233-93288-4" url="/Skywards/skywardLogout/" GroupTitle="Skywards and Business Rewards" GroupCode="SB" GroupID="tcm:233-358296"/>
        </node>
    </node>
</navigation>   

In above xml you will find that there are two type of GroupCode="PB" and GroupCode="SB" , The above XSLT code is doing only one grouping, but there can be lots of GroupCode in the xml and according to that my grouping will done. For above part XML I am looking below output:

<?xml version="1.0" encoding="UTF-8"?>
<navigation path="/english">
    <resources>
        <Copyright>© 2011 mysite. All Rights Reserved.</Copyright>
    </resources>
    <node title="Root" id="tcm:233-38288-4" url="/">
        <node title="030. Plan &amp;amp; Book" id="tcm:233-38446-4" url="/plan_book/plan_and_book.aspx" indexpage="tcm:233-192249-64" compTitle="mysite Online Booking and Planning" imageSrcOn="/Preview/mysiteglobal/english/images/plan_book_highlight_tcm233-343461.gif" imageSrcOff="/Preview/mysiteglobal/english/images/plan_book_tcm233-343460.gif" imageSrcSelected="/Preview/mysiteglobal/english/images/plan_book_active_tcm233-343462.gif" imageSrcSelectedOn="/Preview/mysiteglobal/english/images/plan_book_highlight_tcm233-343461.gif" accessKey="P" GroupTitle="Plan and Book" GroupCode="PB" GroupID="tcm:234-458296">
            <node title="010. Search for a Flight" id="tcm:233-38911-4" url="/IBE.aspx" linktype="ibe" compTitle="Make a Booking" linksection="IBE" accessKey="1"/>
        </node>
        <node title="040. Skywards" id="tcm:233-38448-4" url="/Skywards/skywards.aspx" indexpage="tcm:233-192262-64" compTitle="Skywards" imageSrcOn="/Preview/mysiteglobal/english/images/skywards_highlight_tcm233-343464.gif" imageSrcOff="/Preview/mysiteglobal/english/images/skywards_tcm233-343463.gif" imageSrcSelected="/Preview/mysiteglobal/english/images/skywards_active_tcm233-343465.gif" imageSrcSelectedOn="/Preview/mysiteglobal/english/images/skywards_highlight_tcm233-343464.gif" accessKey="S" GroupTitle="Skywards and Business Rewards" GroupCode="SB" GroupID="tcm:233-358296">
            <node title="080. The mysite High Street" id="tcm:233-59871-4" url="/Skywards/the_mysite_high_street/the_mysite_high_street.aspx" indexpage="tcm:233-346057-64" compTitle="The mysite High Street"/>
            <node title="090. Log In" id="tcm:233-92637-4" url="https://www.skywards.com/index.aspx" indexpage="tcm:233-636665-64" linktype="external" compTitle="Log In"/>
        </node>
    </node>
    <node GroupTitle="Plan and Book" GroupCode="PB" url="/system/ASPX/Link.aspx?ID=tcm:234-458296">
        <nodes>
            <node title="030. Plan &amp;amp; Book" id="tcm:233-38446-4" url="/plan_book/plan_and_book.aspx" indexpage="tcm:233-192249-64" compTitle="mysite Online Booking and Planning" imageSrcOn="/Preview/mysiteglobal/english/images/plan_book_highlight_tcm233-343461.gif" imageSrcOff="/Preview/mysiteglobal/english/images/plan_book_tcm233-343460.gif" imageSrcSelected="/Preview/mysiteglobal/english/images/plan_book_active_tcm233-343462.gif" imageSrcSelectedOn="/Preview/mysiteglobal/english/images/plan_book_highlight_tcm233-343461.gif" accessKey="P"/>
        </nodes>    
    </node> 
    <node GroupTitle="Skywards and Business Rewards" GroupCode="SB" url="/system/ASPX/Link.aspx?ID=tcm:233-358296">
            <node title="035. Business Rewards" id="tcm:233-58061-4" url="/business_rewards/business_rewards.aspx" indexpage="tcm:233-358352-64" compTitle="Business Rewards" imageSrcOn="/Preview/mysiteglobal/english/images/business_rewards_highlight_tcm233-324549.gif" imageSrcOff="/Preview/mysiteglobal/english/images/business_rewards_tcm233-324548.gif" imageSrcSelected="/Preview/mysiteglobal/english/images/business_rewards_active_tcm233-324551.gif" imageSrcSelectedOn="/Preview/mysiteglobal/english/images/business_rewards_highlight_tcm233-324549.gif" authentication="sme-guest">
            </node>
            <node title="040. Skywards" id="tcm:233-38448-4" url="/Skywards/skywards.aspx" indexpage="tcm:233-192262-64" compTitle="Skywards" imageSrcOn="/Preview/mysiteglobal/english/images/skywards_highlight_tcm233-343464.gif" imageSrcOff="/Preview/mysiteglobal/english/images/skywards_tcm233-343463.gif" imageSrcSelected="/Preview/mysiteglobal/english/images/skywards_active_tcm233-343465.gif" imageSrcSelectedOn="/Preview/mysiteglobal/english/images/skywards_highlight_tcm233-343464.gif" accessKey="S">
                <node title="100. Login" id="tcm:233-93287-4" url="/Skywards/skywardLogin/"/>
                <node title="110. Logout" id="tcm:233-93288-4" url="/Skywards/skywardLogout/"/>
            </node>
        </nodes>
    </node>
</navigation>

I modified my above code with below changes and seems its is working for me, please suggest if any changes are required.

<?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:variable name="linkURL" select="'/system/ASPX/Link.aspx?ID='"/>
  <xsl:key name="nodesByGroupsCode" match="*[node[not(@GroupCode)]]" use="@GroupCode" />
  <xsl:template match="*">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates select="node()"/>
      <xsl:if test="self::navigation">
      <xsl:for-each select="//node[generate-id() = generate-id(key('nodesByGroupsCode', @GroupCode)[1])]">       
        <node GroupTitle="{@GroupTitle}" GroupCode="{@GroupCode}" Url="{$linkURL}{@GroupID}">       
          <nodes>    
           <xsl:for-each select="key('nodesByGroupsCode', @GroupCode)"> 
          <xsl:copy> 
           <xsl:apply-templates select="@*" mode="group"/>         
             <xsl:apply-templates select="node()" mode="group"></xsl:apply-templates>       
           </xsl:copy>      
            </xsl:for-each>
          </nodes>            
        </node>    
        </xsl:for-each>    
      </xsl:if>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*[normalize-space(@GroupCode) and not(*[not(normalize-space(@GroupCode))])]"/>

  <xsl:template match="node[normalize-space(@GroupCode)]" mode="group">    
    <xsl:copy>         
      <xsl:apply-templates select="@*" mode="group"/>      
    </xsl:copy>       
  </xsl:template>

  <xsl:template match="*" mode="group"/>

  <xsl:template  match="@*" mode="group">
    <xsl:attribute name="{name()}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>

  <!-- node attributes to be deleted have an empty template each -->
  <xsl:template match="@GroupTitle" mode="group"/>
  <xsl:template match="@GroupCode" mode="group"/>
  <xsl:template match="@GroupID" mode="group"/>

</xsl:stylesheet>

Here is the complete full solution for above issue.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:variable name="linkURL" select="'/system/ASPX/Link.aspx?ID='"/>

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>

     <!-- Key for Group Code attributes -->
    <xsl:key name="node" match="node" use="@GroupCode"/>

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

            <!-- use muenchian for that -->
            <xsl:if test="self::navigation">
                <xsl:for-each select="node/node[generate-id() = generate-id(key('node', @GroupCode)[1])]">
                    <xsl:variable name="this-group-code" select="@GroupCode"/>
                    <node GroupTitle="{@GroupTitle}" GroupCode="{@GroupCode}" Url="{$linkURL}{@GroupID}">
                        <nodes>
                            <!-- push out all the nodes that have this particular group code -->
                            <xsl:apply-templates select="ancestor::navigation/node/node[@GroupCode = $this-group-code]" mode="group"></xsl:apply-templates>
                        </nodes>
                    </node>
                </xsl:for-each>
            </xsl:if>
        </xsl:copy>
    </xsl:template>

    <!-- this template deletes all node that have a group code and no children that don't have a group code -->
    <xsl:template match="*[normalize-space(@GroupCode) and not(*[not(normalize-space(@GroupCode))])]"/>

    <!-- in mode group: copy all node that have a group code-->
    <xsl:template match="node[normalize-space(@GroupCode)]" mode="group">
        <xsl:copy>
            <xsl:apply-templates select="@*" mode="group"/>
            <xsl:apply-templates select="node()" mode="group"/>
        </xsl:copy>            
    </xsl:template>

    <xsl:template match="node" mode="group">
        <xsl:apply-templates select="node()" mode="group"/>
    </xsl:template>

    <!-- group mode: remove all other elements (not specified in higher up templates) -->
    <xsl:template match="*" mode="group"/>

    <!-- in mode group, copy all attributes (except those that have a more specific template match with other instructions -->
    <xsl:template  match="@*" mode="group">
        <xsl:attribute name="{name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>

    <!-- node attributes to be deleted have an empty template each -->
    <xsl:template match="@GroupTitle" mode="group"/>
    <xsl:template match="@GroupCode" mode="group"/>
    <xsl:template match="@GroupID" mode="group"/>
</xsl:stylesheet>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM