Home > Software engineering >  Muenchian Grouping - Group by not appearing in xml result
Muenchian Grouping - Group by not appearing in xml result

Time:09-21

I have the following CSV file such that the XSD looks like this:

123456|123456777|Green|Grün
123456|123456888|Red|Rot
987654|987654333|Yellow|Gelb
In XML format it looks like this:
<Product xmlns="http://F.FlatFileSchema1">
    <Products xmlns="">
        <product>123456</product>
        <sku>123456777</sku>
        <parentcolour_EN>Green</parentcolour_EN>
        <parentcolour_DE>Grün</parentcolour_DE>
    </Products>
    <Products xmlns="">
        <product>123456</product>
        <sku>123456888</sku>
        <parentcolour_EN>Red</parentcolour_EN>
        <parentcolour_DE>Rot</parentcolour_DE>
    </Products>
    <Products xmlns="">
        <product>987654</product>
        <sku>987654333</sku>
        <parentcolour_EN>Yellow</parentcolour_EN>
        <parentcolour_DE>Gelb</parentcolour_DE>
    </Products>
</Product>

The aim is to convert this into an xml with the following format:

<?xml version="1.0" encoding="utf-8"?>
<enfinity xsi:schemaLocation="http://www.intershop.com/xml/ns/enfinity/7.0/xcs/impex catalog.xsd http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt dt.xsd" major="6" minor="1" family="enfinity" branch="enterprise" build="build" xmlns="http://www.intershop.com/xml/ns/enfinity/7.0/xcs/impex" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">
  <offer sku="123456777">
    <custom-attributes>
      <custom-attribute name="parentcolour" dt:dt="string" xml:lang="en-US">Green</custom-attribute>
      <custom-attribute name="parentcolour" dt:dt="string" xml:lang="de-DE">Grün</custom-attribute>
    </custom-attributes>
  </offer>
  <offer sku="123456888">
    <custom-attributes>
      <custom-attribute name="parentcolour" dt:dt="string" xml:lang="en-US">Red</custom-attribute>
      <custom-attribute name="parentcolour" dt:dt="string" xml:lang="de-DE">Rot</custom-attribute>
    </custom-attributes>
  </offer>
  <offer sku="123456">
    <variations>
      <mastered-products>
        <mastered-product sku="123456777" domain="MasterRepository"/>
        <mastered-product sku="123456888" domain="MasterRepository"/>
      </mastered-products>
    </variations>
  </offer>
  <offer sku="987654333">
    <custom-attributes>
      <custom-attribute name="parentcolour" dt:dt="string" xml:lang="en-US">Yellow</custom-attribute>
      <custom-attribute name="parentcolour" dt:dt="string" xml:lang="de-DE">Gelb</custom-attribute>
    </custom-attributes>
  </offer>
  <offer sku="987654">
    <variations>
      <mastered-products>
        <mastered-product sku="987654333" domain="MasterRepository"/>
      </mastered-products>
    </variations>
  </offer>
</enfinity>

As you can see all 3 skus do appear in the XML, but an additional product also needs to appear at the end of the skus, i.e. 123456 appears after 123456777 and 123456888, and 987654 appears after 987654333. So far I am unable to show the variation block for the product level after applying Muenchian grouping. My current XSL looks like this:

<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s0="http://F.FlatFileSchema1" xmlns:xml="http://www.w3.org/XML/1998/namespace" exclude-result-prefixes="s0">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:key name="groupbyproduct" match="offer" use="product"/>
    <xsl:template match="/s0:Product">
        <enfinity xsi:schemaLocation="http://www.intershop.com/xml/ns/enfinity/7.0/xcs/impex catalog.xsd http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt dt.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.intershop.com/xml/ns/enfinity/7.0/xcs/impex" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt" major="6" minor="1" family="enfinity" branch="enterprise" build="build">
            <xsl:for-each select="Products">
                <offer sku="{sku}">
                    <custom-attributes>
                        <custom-attribute name="parentcolour" dt:dt="string" xml:lang="en-US">
                            <xsl:value-of select="parentcolour_EN/text()"/>
                        </custom-attribute>
                        <custom-attribute name="parentcolour" dt:dt="string" xml:lang="de-DE">
                            <xsl:value-of select="parentcolour_DE/text()"/>
                        </custom-attribute>
                    </custom-attributes>
                </offer>
            </xsl:for-each>
            <!-- create a group for each unique product -->
            <xsl:for-each select="offer[count(. | key('groupbyproduct', product)[1]) = 1]">
                <offer sku="{product}">
                    <variations>
                        <mastered-products>
                            <!-- for each member of current group -->
                            <xsl:for-each select="key('groupbyproduct', product)">
                                <mastered-product sku="{sku}" domain="MasterRepository"/>
                            </xsl:for-each>
                        </mastered-products>
                    </variations>
                </offer>
            </xsl:for-each>
        </enfinity>
    </xsl:template>
</xsl:stylesheet>

CodePudding user response:

The key doesn't make sense, I think you want <xsl:key name="groupbyproduct" match="Products" use="product"/> and then instead of the second for-each you want

        <!-- create a group for each unique product -->
        <xsl:for-each select="Products[count(. | key('groupbyproduct', product)[1]) = 1]">
            <offer sku="{product}">
                <variations>
                    <mastered-products>
                        <!-- for each member of current group -->
                        <xsl:for-each select="key('groupbyproduct', product)">
                            <mastered-product sku="{sku}" domain="MasterRepository"/>
                        </xsl:for-each>
                    </mastered-products>
                </variations>
            </offer>
        </xsl:for-each>

As for your comment and the complete result you want, it looks as if first grouping and then inside outputting the different data should give the order you want:

    <xsl:for-each select="Products[count(. | key('groupbyproduct', product)[1]) = 1]">
      <xsl:for-each select="key('groupbyproduct', product)">
            <offer sku="{sku}">
                <custom-attributes>
                    <custom-attribute name="parentcolour" dt:dt="string" xml:lang="en-US">
                        <xsl:value-of select="parentcolour_EN/text()"/>
                    </custom-attribute>
                    <custom-attribute name="parentcolour" dt:dt="string" xml:lang="de-DE">
                        <xsl:value-of select="parentcolour_DE/text()"/>
                    </custom-attribute>
                </custom-attributes>
            </offer>
        </xsl:for-each>
        <offer sku="{product}">
            <variations>
                <mastered-products>
                    <!-- for each member of current group -->
                    <xsl:for-each select="key('groupbyproduct', product)">
                        <mastered-product sku="{sku}" domain="MasterRepository"/>
                    </xsl:for-each>
                </mastered-products>
            </variations>
        </offer>
    </xsl:for-each>
  • Related