Многоуровневая группировка мужских языков

#xslt #xslt-1.0 #biztalk #muenchian-grouping

Вопрос:

Я знаю, что есть более простой способ сделать это, но пока я ограничен использованием XSLT1.0, поэтому мне приходится использовать группировку по-мужски.

У меня есть следующий XML:

 <Root xmlns="http://MuleSoft.Attraqt.FlatFileSchema1">
    <Root_Child1 xmlns="">
        <sku>123456777</sku>
        <ProductMaster>123456</ProductMaster>
        <default>yes</default>
        <category>UK</category>
        <display_name>UK Web Categories</display_name>
    </Root_Child1>
    <Root_Child1 xmlns="">
        <sku>123456777</sku>
        <ProductMaster>123456</ProductMaster>
        <default>no</default>
        <category>DE</category>
        <display_name>DE Web Categories</display_name>
    </Root_Child1>
    <Root_Child1 xmlns="">
        <sku>123456999</sku>
        <ProductMaster>123456</ProductMaster>
        <default>yes</default>
        <category>UK</category>
        <display_name>UK Web Categories</display_name>
    </Root_Child1>
    <Root_Child1 xmlns="">
        <sku>123456999</sku>
        <ProductMaster>123456</ProductMaster>
        <default>no</default>
        <category>DE</category>
        <display_name>DE Web Categories</display_name>
    </Root_Child1>
    <Root_Child1 xmlns="">
        <sku>987654333</sku>
        <ProductMaster>987654</ProductMaster>
        <default>no</default>
        <category>UK</category>
        <display_name>UK Web Categories</display_name>
    </Root_Child1>
    <Root_Child1 xmlns="">
        <sku>987654333</sku>
        <ProductMaster>987654</ProductMaster>
        <default>no</default>
        <category>DE</category>
        <display_name>DE Web Categories</display_name>
    </Root_Child1>
    <Root_Child1 xmlns="">
        <sku>987654333</sku>
        <ProductMaster>987654</ProductMaster>
        <default>yes</default>
        <category>GLOBAL</category>
        <display_name>GLOBAL Web Categories</display_name>
    </Root_Child1>
</Root>
 

Вместо этого я хочу преобразовать его в этот формат:

 <?xml version='1.0' encoding='UTF-8'?>
<records>
  <record>
    <fields>
      <field name="ProductMaster">
        <values>
          <value>123456</value>
        </values>
      </field>
      <field name="size">
        <attributes>
          <attribute>
            <field name="sku">
              <values>
                <value>123456777</value>
              </values>
            </field>
          </attribute>
          <attribute>
            <field name="sku">
              <values>
                <value>123456999</value>
              </values>
            </field>
          </attribute>
        </attributes>
      </field>
    </fields>
    <categories>
      <categorytree>
        <category default="yes" uniqueid="UK">UK Web Categories</category>
      </categorytree>
      <categorytree>
        <category default="no" uniqueid="DE">DE Web Categories</category>
      </categorytree>
    </categories>
  </record>
  <record>
    <fields>
      <field name="ProductMaster">
        <values>
          <value>987654</value>
        </values>
      </field>
      <field name="size">
        <attributes>
          <attribute>
            <field name="sku">
              <values>
                <value>987654333</value>
              </values>
            </field>
          </attribute>
        </attributes>
      </field>
    </fields>
    <categories>
      <categorytree>
        <category default="no" uniqueid="UK">UK Web Categories</category>
      </categorytree>
      <categorytree>
        <category default="no" uniqueid="DE">DE Web Categories</category>
      </categorytree>
      <categorytree>
        <category default="yes" uniqueid="GLOBAL">GLOBAL Web Categories</category>
      </categorytree>
    </categories>
  </record>
</records> 
 

Basically in each <record></record> block there should be 1 ProductMaster (which I can get).
Then within <attributes></attributes> it needs to cycle through that ProductMaster and show each sku (but only once, currently mine only shows one sku)
Then in the next <categorytree></categorytree> it needs to show each category (also only once, currently mine shows duplicates). I started off with the XSLT1.0 below which got me the first <record></record> grouping correctly but I can’t figure out how to get the next 2 groupings correctly. Notice I have created 2 more keys to assist but I have no idea how to use them:

 <?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" exclude-result-prefixes="msxsl var s0" version="1.0" xmlns:s0="http://MuleSoft.Attraqt.FlatFileSchema1">
    <xsl:output method="xml" version="1.0" indent="yes"/>
    <xsl:key name="groupbyproduct" match="Root_Child1" use="ProductMaster"/>
    <xsl:key name="groupbysku" match="Root_Child1" use="concat(ProductMaster,'|',sku)"/>
    <xsl:key name="groupbycategory" match="Root_Child1" use="concat(ProductMaster,'|',category)"/>
    <xsl:template match="/s0:Root">
        <records>
            <xsl:for-each select="Root_Child1[count(. | key('groupbyproduct', ProductMaster)[1]) = 1]">
                <record>
                    <fields>
                        <field name="ProductMaster">
                            <values>
                                <value>
                                    <xsl:value-of select="ProductMaster/text()"/>
                                </value>
                            </values>
                        </field>
                        <field name="size">
                            <attributes>
                                <attribute>
                                    <field name="sku">
                                        <values>
                                            <value>
                                                <xsl:value-of select="sku/text()"/>
                                            </value>
                                        </values>
                                    </field>
                                </attribute>
                            </attributes>
                        </field>
                    </fields>
                    <categories>
                        <!-- for each member of current group -->
                        <xsl:for-each select="key('groupbyproduct', ProductMaster)">
                            <categorytree>
                                <category default="{default}" uniqueid="{category}">
                                    <xsl:value-of select="display_name/text()"/>
                                </category>
                            </categorytree>
                        </xsl:for-each>
                    </categories>
                </record>
            </xsl:for-each>
        </records>
    </xsl:template>
</xsl:stylesheet>```