0

completely new to xlst, I've tried to follow numerous links to apply Muenchian grouping but to no avail, most likely because I'm not putting the extra lines in the right places probably, and have no idea how to convert to xlst2 in order to use for-each-group instead. Anyway the csv file I'm trying to convert is very simple:

123456789,2021-08-05T00:00:00+00:00,GBP,2099-12-31T00:00:00+00:00,23.00
123456789,2021-07-22T00:00:00+00:00,GBP,2099-07-22T00:00:00+00:00,35.00
123456789,2021-07-06T00:00:00+00:00,GBP,2099-07-13T00:00:00+00:00,39.50
987654321,2021-08-05T00:00:00+00:00,EUR,2099-12-31T00:00:00+00:00,25.95
987654321,2021-07-22T00:00:00+00:00,EUR,2099-07-22T00:00:00+00:00,39.95
987654321,2021-07-06T00:00:00+00:00,EUR,2099-07-13T00:00:00+00:00,44.95

Or in XML format:

<DEMarkdown xmlns="http://F.FlatFileSchema1">
    <DEMarkdowns xmlns="">
        <sku>123456789</sku>
        <valid-from>2021-08-05T00:00:00+00:00</valid-from>
        <currency>GBP</currency>
        <valid-to>2099-12-31T00:00:00+00:00</valid-to>
        <value>23.00</value>
    </DEMarkdowns>
    <DEMarkdowns xmlns="">
        <sku>123456789</sku>
        <valid-from>2021-07-22T00:00:00+00:00</valid-from>
        <currency>GBP</currency>
        <valid-to>2099-07-22T00:00:00+00:00</valid-to>
        <value>35.00</value>
    </DEMarkdowns>
    <DEMarkdowns xmlns="">
        <sku>123456789</sku>
        <valid-from>2021-07-06T00:00:00+00:00</valid-from>
        <currency>GBP</currency>
        <valid-to>2099-07-13T00:00:00+00:00</valid-to>
        <value>39.50</value>
    </DEMarkdowns>
    <DEMarkdowns xmlns="">
        <sku>987654321</sku>
        <valid-from>2021-08-05T00:00:00+00:00</valid-from>
        <currency>EUR</currency>
        <valid-to>2099-12-31T00:00:00+00:00</valid-to>
        <value>25.95</value>
    </DEMarkdowns>
    <DEMarkdowns xmlns="">
        <sku>987654321</sku>
        <valid-from>2021-07-22T00:00:00+00:00</valid-from>
        <currency>EUR</currency>
        <valid-to>2099-07-22T00:00:00+00:00</valid-to>
        <value>39.95</value>
    </DEMarkdowns>
    <DEMarkdowns xmlns="">
        <sku>987654321</sku>
        <valid-from>2021-07-06T00:00:00+00:00</valid-from>
        <currency>EUR</currency>
        <valid-to>2099-07-13T00:00:00+00:00</valid-to>
        <value>44.95</value>
    </DEMarkdowns>
</DEMarkdown>

I've used BizTalk to generate my Flat File Source Schema:

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://F.FlatFileSchema1" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://F.FlatFileSchema1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:annotation>
    <xs:appinfo>
      <schemaEditorExtension:schemaInfo namespaceAlias="b" extensionClass="Microsoft.BizTalk.FlatFileExtension.FlatFileExtension" standardName="Flat File" xmlns:schemaEditorExtension="http://schemas.microsoft.com/BizTalk/2003/SchemaEditorExtensions" />
      <b:schemaInfo standard="Flat File" codepage="65001" default_pad_char=" " pad_char_type="char" count_positions_by_byte="false" parser_optimization="speed" lookahead_depth="3" suppress_empty_nodes="false" generate_empty_nodes="true" allow_early_termination="false" early_terminate_optional_fields="false" allow_message_breakup_of_infix_root="false" compile_parse_tables="false" root_reference="DEMarkdown" />
    </xs:appinfo>
  </xs:annotation>
  <xs:element name="DEMarkdown">
    <xs:annotation>
      <xs:appinfo>
        <b:recordInfo structure="delimited" child_delimiter_type="hex" child_delimiter="0xD 0xA" child_order="postfix" sequence_number="1" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" />
      </xs:appinfo>
    </xs:annotation>
    <xs:complexType>
      <xs:sequence>
        <xs:annotation>
          <xs:appinfo>
            <groupInfo sequence_number="0" xmlns="http://schemas.microsoft.com/BizTalk/2003" />
          </xs:appinfo>
        </xs:annotation>
        <xs:element maxOccurs="unbounded" name="DEMarkdowns">
          <xs:annotation>
            <xs:appinfo>
              <b:recordInfo structure="delimited" child_delimiter_type="char" child_delimiter="," child_order="infix" sequence_number="1" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" />
            </xs:appinfo>
          </xs:annotation>
          <xs:complexType>
            <xs:sequence>
              <xs:annotation>
                <xs:appinfo>
                  <groupInfo sequence_number="0" xmlns="http://schemas.microsoft.com/BizTalk/2003" />
                </xs:appinfo>
              </xs:annotation>
              <xs:element name="sku" type="xs:string">
                <xs:annotation>
                  <xs:appinfo>
                    <b:fieldInfo justification="left" sequence_number="1" />
                  </xs:appinfo>
                </xs:annotation>
              </xs:element>
              <xs:element name="valid-from" type="xs:dateTime">
                <xs:annotation>
                  <xs:appinfo>
                    <b:fieldInfo justification="left" sequence_number="2" />
                  </xs:appinfo>
                </xs:annotation>
              </xs:element>
              <xs:element name="currency" type="xs:string">
                <xs:annotation>
                  <xs:appinfo>
                    <b:fieldInfo justification="left" sequence_number="3" />
                  </xs:appinfo>
                </xs:annotation>
              </xs:element>
              <xs:element name="valid-to" type="xs:dateTime">
                <xs:annotation>
                  <xs:appinfo>
                    <b:fieldInfo justification="left" sequence_number="4" />
                  </xs:appinfo>
                </xs:annotation>
              </xs:element>
              <xs:element name="value" type="xs:decimal">
                <xs:annotation>
                  <xs:appinfo>
                    <b:fieldInfo justification="left" sequence_number="5" />
                  </xs:appinfo>
                </xs:annotation>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

The XML destination schema is this:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dt="http://www.fakewebsite.com/xml/ns/enfinity/6.5/core/impex-dt" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.fakewebsite.com/7.1/bc_pricing/impex" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="enfinity">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="product-price-list">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="display-name" type="xs:string" />
                            <xs:element name="description" type="xs:string" />
                            <xs:element name="enabled" type="xs:boolean" />
                            <xs:element name="priority" type="xs:unsignedByte" />
                            <xs:element name="target-groups">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="customer-segments">
                                            <xs:complexType>
                                                <xs:sequence>
                                                    <xs:element maxOccurs="unbounded" name="customer-segment">
                                                        <xs:complexType>
                                                            <xs:attribute name="id" type="xs:string" use="required" />
                                                            <xs:attribute name="repository-id" type="xs:string" use="required" />
                                                        </xs:complexType>
                                                    </xs:element>
                                                </xs:sequence>
                                            </xs:complexType>
                                        </xs:element>
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                            <xs:element maxOccurs="unbounded" name="product-price-list-entry">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element maxOccurs="unbounded" name="price-scale-table">
                                            <xs:complexType>
                                                <xs:sequence>
                                                    <xs:element name="valid-from" type="xs:dateTime" />
                                                    <xs:element name="valid-to" type="xs:dateTime" />
                                                    <xs:element name="price-scale-entries">
                                                        <xs:complexType>
                                                            <xs:sequence>
                                                                <xs:element name="fixed-price-entry">
                                                                    <xs:complexType>
                                                                        <xs:sequence>
                                                                            <xs:element name="value" type="xs:decimal" />
                                                                        </xs:sequence>
                                                                        <xs:attribute name="quantity" type="xs:unsignedByte" use="required" />
                                                                        <xs:attribute name="unit" type="xs:string" use="required" />
                                                                    </xs:complexType>
                                                                </xs:element>
                                                            </xs:sequence>
                                                        </xs:complexType>
                                                    </xs:element>
                                                </xs:sequence>
                                                <xs:attribute name="type-code" type="xs:unsignedByte" use="required" />
                                                <xs:attribute name="currency" type="xs:string" use="required" />
                                            </xs:complexType>
                                        </xs:element>
                                    </xs:sequence>
                                    <xs:attribute name="sku" type="xs:unsignedInt" use="required" />
                                    <xs:attribute name="import-mode" type="xs:string" use="required" />
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                        <xs:attribute name="id" type="xs:string" use="required" />
                        <xs:attribute name="priceType" type="xs:string" use="required" />
                        <xs:attribute name="import-mode" type="xs:string" use="required" />
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute name="major" type="xs:unsignedByte" use="required" />
            <xs:attribute name="minor" type="xs:unsignedByte" use="required" />
            <xs:attribute name="family" type="xs:string" use="required" />
            <xs:attribute name="branch" type="xs:string" use="required" />
            <xs:attribute name="build" type="xs:string" use="required" />
        </xs:complexType>
    </xs:element>
</xs:schema>

The current output of my XML looks like this at the moment:

<?xml version="1.0" encoding="utf-8"?>
<ns0:enfinity major="6" minor="1" family="enfinity" branch="enterprise" build="build" xmlns:ns0="http://www.fakewebsite.com/7.1/bc_pricing/impex" xmlns:s0="http://F.FlatFileSchema1">
    <ns0:product-price-list id="DEMarkdown" priceType="ES_SalePrice" import-mode="UPDATE">
        <ns0:display-name>DE Markdown</ns0:display-name>
        <ns0:description/>
        <ns0:enabled>true</ns0:enabled>
        <ns0:priority>1</ns0:priority>
        <ns0:target-groups>
            <ns0:customer-segments>
                <ns0:customer-segment id="Everyone" repository-id="WhiteStuff-DE-Anonymous"/>
                <ns0:customer-segment id="IG_RegisteredUsers" repository-id="WhiteStuff-DE-Anonymous"/>
            </ns0:customer-segments>
        </ns0:target-groups>
        <ns0:product-price-list-entry sku="123456789" import-mode="REPLACE">
            <ns0:price-scale-table type-code="1" currency="GBP">
                <ns0:valid-from>2021-08-05T00:00:00+00:00</ns0:valid-from>
                <ns0:valid-to>2099-12-31T00:00:00+00:00</ns0:valid-to>
                <ns0:price-scale-entries>
                    <ns0:fixed-price-entry quantity="1" unit="">
                        <ns0:value>23.00</ns0:value>
                    </ns0:fixed-price-entry>
                </ns0:price-scale-entries>
            </ns0:price-scale-table>
        </ns0:product-price-list-entry>
        <ns0:product-price-list-entry sku="123456789" import-mode="REPLACE">
            <ns0:price-scale-table type-code="1" currency="GBP">
                <ns0:valid-from>2021-07-22T00:00:00+00:00</ns0:valid-from>
                <ns0:valid-to>2099-07-22T00:00:00+00:00</ns0:valid-to>
                <ns0:price-scale-entries>
                    <ns0:fixed-price-entry quantity="1" unit="">
                        <ns0:value>35.00</ns0:value>
                    </ns0:fixed-price-entry>
                </ns0:price-scale-entries>
            </ns0:price-scale-table>
        </ns0:product-price-list-entry>
        <ns0:product-price-list-entry sku="123456789" import-mode="REPLACE">
            <ns0:price-scale-table type-code="1" currency="GBP">
                <ns0:valid-from>2021-07-06T00:00:00+00:00</ns0:valid-from>
                <ns0:valid-to>2099-07-13T00:00:00+00:00</ns0:valid-to>
                <ns0:price-scale-entries>
                    <ns0:fixed-price-entry quantity="1" unit="">
                        <ns0:value>39.50</ns0:value>
                    </ns0:fixed-price-entry>
                </ns0:price-scale-entries>
            </ns0:price-scale-table>
        </ns0:product-price-list-entry>
        <ns0:product-price-list-entry sku="987654321" import-mode="REPLACE">
            <ns0:price-scale-table type-code="1" currency="EUR">
                <ns0:valid-from>2021-08-05T00:00:00+00:00</ns0:valid-from>
                <ns0:valid-to>2099-12-31T00:00:00+00:00</ns0:valid-to>
                <ns0:price-scale-entries>
                    <ns0:fixed-price-entry quantity="1" unit="">
                        <ns0:value>25.95</ns0:value>
                    </ns0:fixed-price-entry>
                </ns0:price-scale-entries>
            </ns0:price-scale-table>
        </ns0:product-price-list-entry>
        <ns0:product-price-list-entry sku="987654321" import-mode="REPLACE">
            <ns0:price-scale-table type-code="1" currency="EUR">
                <ns0:valid-from>2021-07-22T00:00:00+00:00</ns0:valid-from>
                <ns0:valid-to>2099-07-22T00:00:00+00:00</ns0:valid-to>
                <ns0:price-scale-entries>
                    <ns0:fixed-price-entry quantity="1" unit="">
                        <ns0:value>39.95</ns0:value>
                    </ns0:fixed-price-entry>
                </ns0:price-scale-entries>
            </ns0:price-scale-table>
        </ns0:product-price-list-entry>
        <ns0:product-price-list-entry sku="987654321" import-mode="REPLACE">
            <ns0:price-scale-table type-code="1" currency="EUR">
                <ns0:valid-from>2021-07-06T00:00:00+00:00</ns0:valid-from>
                <ns0:valid-to>2099-07-13T00:00:00+00:00</ns0:valid-to>
                <ns0:price-scale-entries>
                    <ns0:fixed-price-entry quantity="1" unit="">
                        <ns0:value>44.95</ns0:value>
                    </ns0:fixed-price-entry>
                </ns0:price-scale-entries>
            </ns0:price-scale-table>
        </ns0:product-price-list-entry>
    </ns0:product-price-list>
</ns0:enfinity>

But I want to group by sku so each sku only appears once within product-price-list-entry, so that it looks like this instead:

<enfinity xsi:schemaLocation="http://www.fakewebsite.com/7.1/bc_pricing/impex bc_pricing.xsd" xmlns="http://www.fakewebsite.com/7.1/bc_pricing/impex" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dt="http://www.fakewebsite.com/6.5/core/impex-dt" major="6" minor="1" family="enfinity" branch="enterprise" build="build">
  <product-price-list id="DEMarkdown" priceType="ES_SalePrice" import-mode="UPDATE">
    <display-name>DE Markdown</display-name>
    <description></description>
    <enabled>true</enabled>
    <priority>1</priority>
    <target-groups>
      <customer-segments>
        <customer-segment id="Everyone" repository-id="WhiteStuff-DE-Anonymous"/>
        <customer-segment id="IG_RegisteredUsers" repository-id="WhiteStuff-DE-Anonymous"/>
      </customer-segments>
    </target-groups>
    <product-price-list-entry sku="123456789" import-mode="REPLACE">
      <price-scale-table type-code="1" currency="GBP">
        <valid-from>2021-08-05T00:00:00+00:00</valid-from>
        <valid-to>2099-12-31T00:00:00+00:00</valid-to>
        <price-scale-entries>
          <fixed-price-entry quantity="1" unit="">
            <value>23.00</value>
          </fixed-price-entry>
        </price-scale-entries>
      </price-scale-table>
      <price-scale-table type-code="1" currency="GBP">
        <valid-from>2021-07-22T00:00:00+00:00</valid-from>
        <valid-to>2099-07-22T00:00:00+00:00</valid-to>
        <price-scale-entries>
          <fixed-price-entry quantity="1" unit="">
            <value>35.00</value>
          </fixed-price-entry>
        </price-scale-entries>
      </price-scale-table>
      <price-scale-table type-code="1" currency="EUR">
        <valid-from>2021-07-22T00:00:00+00:00</valid-from>
        <valid-to>2099-07-22T00:00:00+00:00</valid-to>
        <price-scale-entries>
          <fixed-price-entry quantity="1" unit="">
            <value>39.95</value>
          </fixed-price-entry>
        </price-scale-entries>
      </price-scale-table>
    </product-price-list-entry>
    <product-price-list-entry sku="987654321" import-mode="REPLACE">
      <price-scale-table type-code="1" currency="EUR">
        <valid-from>2021-08-05T00:00:00+00:00</valid-from>
        <valid-to>2099-12-31T00:00:00+00:00</valid-to>
        <price-scale-entries>
          <fixed-price-entry quantity="1" unit="">
            <value>25.95</value>
          </fixed-price-entry>
        </price-scale-entries>
      </price-scale-table>
      <price-scale-table type-code="1" currency="GBP">
        <valid-from>2021-07-05T00:00:00+00:00</valid-from>
        <valid-to>2099-07-13T00:00:00+00:00</valid-to>
        <price-scale-entries>
          <fixed-price-entry quantity="1" unit="">
            <value>39.50</value>
          </fixed-price-entry>
        </price-scale-entries>
      </price-scale-table>
      <price-scale-table type-code="1" currency="EUR">
        <valid-from>2021-07-05T00:00:00+00:00</valid-from>
        <valid-to>2099-07-13T00:00:00+00:00</valid-to>
        <price-scale-entries>
          <fixed-price-entry quantity="1" unit="">
            <value>44.95</value>
          </fixed-price-entry>
        </price-scale-entries>
      </price-scale-table>
    </product-price-list-entry>
  </product-price-list>
</enfinity>

The xlst which currently converts csv to xml is this, which is what I'm trying to modify. I've taken out what I tried to add myself as it didn't work :(

<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:ns0="http://www.fakewebsite.com/7.1/bc_pricing/impex" xmlns:s0="http://F.FlatFileSchema1">
    <xsl:output method="xml" indent="no"/>
    <xsl:template match="/">
        <xsl:apply-templates select="/s0:DEMarkdown"/>
    </xsl:template>
    <xsl:template match="/s0:DEMarkdown">
        <ns0:enfinity>
            <xsl:attribute name="major">
                <xsl:text>6</xsl:text>
            </xsl:attribute>
            <xsl:attribute name="minor">
                <xsl:text>1</xsl:text>
            </xsl:attribute>
            <xsl:attribute name="family">
                <xsl:text>enfinity</xsl:text>
            </xsl:attribute>
            <xsl:attribute name="branch">
                <xsl:text>enterprise</xsl:text>
            </xsl:attribute>
            <xsl:attribute name="build">
                <xsl:text>build</xsl:text>
            </xsl:attribute>
            <ns0:product-price-list>
                <xsl:attribute name="id">
                    <xsl:text>DEMarkdown</xsl:text>
                </xsl:attribute>
                <xsl:attribute name="priceType">
                    <xsl:text>ES_SalePrice</xsl:text>
                </xsl:attribute>
                <xsl:attribute name="import-mode">
                    <xsl:text>UPDATE</xsl:text>
                </xsl:attribute>
                <ns0:display-name>
                    <xsl:text>DE Markdown</xsl:text>
                </ns0:display-name>
                <ns0:description>
                    <xsl:text/>
                </ns0:description>
                <ns0:enabled>
                    <xsl:text>true</xsl:text>
                </ns0:enabled>
                <ns0:priority>
                    <xsl:text>1</xsl:text>
                </ns0:priority>
                <ns0:target-groups>
                    <ns0:customer-segments>
                        <ns0:customer-segment>
                            <xsl:attribute name="id">
                                <xsl:text>Everyone</xsl:text>
                            </xsl:attribute>
                            <xsl:attribute name="repository-id">
                                <xsl:text>WhiteStuff-DE-Anonymous</xsl:text>
                            </xsl:attribute>
                        </ns0:customer-segment>
                        <ns0:customer-segment>
                            <xsl:attribute name="id">
                                <xsl:text>IG_RegisteredUsers</xsl:text>
                            </xsl:attribute>
                            <xsl:attribute name="repository-id">
                                <xsl:text>WhiteStuff-DE-Anonymous</xsl:text>
                            </xsl:attribute>
                        </ns0:customer-segment>
                    </ns0:customer-segments>
                </ns0:target-groups>
                <xsl:for-each select="DEMarkdowns">
                    <ns0:product-price-list-entry>
                        <xsl:attribute name="sku">
                            <xsl:value-of select="sku/text()"/>
                        </xsl:attribute>
                        <xsl:attribute name="import-mode">
                            <xsl:text>REPLACE</xsl:text>
                        </xsl:attribute>
                        <ns0:price-scale-table>
                            <xsl:attribute name="type-code">
                                <xsl:text>1</xsl:text>
                            </xsl:attribute>
                            <xsl:attribute name="currency">
                                <xsl:value-of select="currency/text()"/>
                            </xsl:attribute>
                            <ns0:valid-from>
                                <xsl:value-of select="valid-from/text()"/>
                            </ns0:valid-from>
                            <ns0:valid-to>
                                <xsl:value-of select="valid-to/text()"/>
                            </ns0:valid-to>
                            <ns0:price-scale-entries>
                                <ns0:fixed-price-entry>
                                    <xsl:attribute name="quantity">
                                        <xsl:text>1</xsl:text>
                                    </xsl:attribute>
                                    <xsl:attribute name="unit">
                                        <xsl:text/>
                                    </xsl:attribute>
                                    <ns0:value>
                                        <xsl:value-of select="value/text()"/>
                                    </ns0:value>
                                </ns0:fixed-price-entry>
                            </ns0:price-scale-entries>
                        </ns0:price-scale-table>
                    </ns0:product-price-list-entry>
                </xsl:for-each>
            </ns0:product-price-list>
        </ns0:enfinity>
    </xsl:template>
</xsl:stylesheet>
tommyhmt
  • 145
  • 2
  • 11
  • Please edit your question and add the input XML. – michael.hor257k Sep 07 '21 at 15:20
  • You should certainly consider using XSLT 2.0 instead. What platform/environment are you running in? – Michael Kay Sep 07 '21 at 17:45
  • Hi @MichaelKay, I'm not an XSLT programmer so there are probably better tools out there, but I just used BizTalk to generate the XSL which was only available for 1.0, especially when the csv and xml file were both quite straight forward (or at least I thought). I did have a quick look online to see if I can convert that to XSLT 2.0 but looks like there is a cost to it, and more extensive XSLT language skills. – tommyhmt Sep 07 '21 at 20:52
  • Hi @michael.hor257k, just updated the input file which is in CSV format, hope you can assist. Thanks in advance. – tommyhmt Sep 07 '21 at 20:57
  • The input to XSL transformation is XML, not CSV (at least not in XSLT 1.0). Apparently you are using some application that converts CSV to XML and feeds it as the input to the XSLT processor. We need to see that raw XML. Try using a stylesheet that contains only [identity transform](https://en.wikipedia.org/wiki/Identity_transform#Using_XSLT) to get it. While you're at it, knowing which processor is being used could also be helpful - see here how to get that: https://stackoverflow.com/a/25245033/3016153 – michael.hor257k Sep 07 '21 at 21:04
  • Hi @michael.hor257k, I've edited my original post to include the source and destination xsd files, is that what you meant? – tommyhmt Sep 07 '21 at 22:05
  • No, it is not. I want to see the actual XML file, with sample data (as shown in your CSV), prior to the transformation. – michael.hor257k Sep 07 '21 at 22:10
  • @tommyhmt I understand where you're coming from but on the skills front, things like grouping and character manipulation in XSLT 1.0 are much more difficult in 1.0 than in 2.0, which is why I made the suggestion. Your code would also be about one third the size in 2.0 because of the `xsl:attribute` verbosity. – Michael Kay Sep 07 '21 at 22:18
  • It could be one third in size in XSLT 1.0 too. – michael.hor257k Sep 07 '21 at 22:25
  • @michael.hor257k, I've included the XML version of the CSV file, hopefully that's what you meant this time. – tommyhmt Sep 07 '21 at 22:27
  • Yes. Are you able to provide the processor details too? – michael.hor257k Sep 07 '21 at 22:28
  • Thanks so much @michael.hor257k, that worked a treat. Reason why I had such problems with it is because as I said I've never dealt with xslt files before, although it turns out I was only one line away from making it work which is a little bit more frustrating. My lack of experience also explains the unnecssary verbosity as the original xslt file was generated by BizTalk and I had no idea it could be written using attribute value templates instead. – tommyhmt Sep 07 '21 at 23:08
  • Hi @michael.hor257k, just realised that the element "description" should always be blank but it's only displaying: Also can the top line show this instead? – tommyhmt Sep 08 '21 at 22:03
  • Please do not post code in comments. If necessary, edit your question or post a new one. FYI, `` **is** an empty element, so I am not sure what you're talking about. And I believe you can simply add all those attributes and namespace declarations to the `enfinity` start tag. In any case, none of this has anything to do with Muenchian grouping - so if you can't make it work, post a new question. – michael.hor257k Sep 08 '21 at 22:33

1 Answers1

0

Let me start with something irrelevant to your question, but still pertinent to the topic, IMHO: your current stylesheet is unduly verbose. As noted in the comments, it could be reduced significantly by using attribute value templates instead of xsl:attribute instructions. In addition, the first template is entirely redundant, as this is taken care of by the built-in template rules. And a few other things. I have taken the liberty of removing all that unnecessary verbosity.

Other than that, this is a pretty standard implementation of Muenchian grouping - not sure why you had such problems with it:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns="http://www.fakewebsite.com/7.1/bc_pricing/impex" 
xmlns:s0="http://F.FlatFileSchema1"
exclude-result-prefixes="s0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="prod" match="DEMarkdowns" use="sku" />
    
<xsl:template match="/s0:DEMarkdown">
    <enfinity major="6" minor="1" family="enfinity" branch="enterprise" build="build">
        <product-price-list id="DEMarkdown" priceType="ES_SalePrice" import-mode="UPDATE">
            <display-name>DE Markdown</display-name>
            <description></description>
            <enabled>true</enabled>
            <priority>1</priority>
            <target-groups>
                <customer-segments>
                    <customer-segment id="Everyone" repository-id="WhiteStuff-DE-Anonymous"/>
                    <customer-segment id="IG_RegisteredUsers" repository-id="WhiteStuff-DE-Anonymous"/>
                </customer-segments>
            </target-groups>
            <!-- create a group for each unique sku -->
            <xsl:for-each select="DEMarkdowns[count(. | key('prod', sku)[1]) = 1]">
                <product-price-list-entry sku="{sku}" import-mode="REPLACE">
                    <!-- for each member of current group -->
                    <xsl:for-each select="key('prod', sku)">
                        <price-scale-table type-code="1" currency="{currency}">
                            <valid-from>
                                <xsl:value-of select="valid-from"/>
                            </valid-from>
                            <valid-to>
                                <xsl:value-of select="valid-to"/>
                            </valid-to>
                            <price-scale-entries>
                                <fixed-price-entry quantity="1" unit="">
                                    <value>
                                        <xsl:value-of select="value"/>
                                    </value>
                                </fixed-price-entry>
                            </price-scale-entries>
                        </price-scale-table>
                    </xsl:for-each>
                </product-price-list-entry>
            </xsl:for-each>
        </product-price-list>
    </enfinity>
</xsl:template>

</xsl:stylesheet>

Applied to your input example,, this will generate:

Result

<?xml version="1.0" encoding="UTF-8"?>
<enfinity xmlns="http://www.fakewebsite.com/7.1/bc_pricing/impex" major="6" minor="1" family="enfinity" branch="enterprise" build="build">
  <product-price-list id="DEMarkdown" priceType="ES_SalePrice" import-mode="UPDATE">
    <display-name>DE Markdown</display-name>
    <description/>
    <enabled>true</enabled>
    <priority>1</priority>
    <target-groups>
      <customer-segments>
        <customer-segment id="Everyone" repository-id="WhiteStuff-DE-Anonymous"/>
        <customer-segment id="IG_RegisteredUsers" repository-id="WhiteStuff-DE-Anonymous"/>
      </customer-segments>
    </target-groups>
    <product-price-list-entry sku="123456789" import-mode="REPLACE">
      <price-scale-table type-code="1" currency="GBP">
        <valid-from>2021-08-05T00:00:00+00:00</valid-from>
        <valid-to>2099-12-31T00:00:00+00:00</valid-to>
        <price-scale-entries>
          <fixed-price-entry quantity="1" unit="">
            <value>23.00</value>
          </fixed-price-entry>
        </price-scale-entries>
      </price-scale-table>
      <price-scale-table type-code="1" currency="GBP">
        <valid-from>2021-07-22T00:00:00+00:00</valid-from>
        <valid-to>2099-07-22T00:00:00+00:00</valid-to>
        <price-scale-entries>
          <fixed-price-entry quantity="1" unit="">
            <value>35.00</value>
          </fixed-price-entry>
        </price-scale-entries>
      </price-scale-table>
      <price-scale-table type-code="1" currency="GBP">
        <valid-from>2021-07-06T00:00:00+00:00</valid-from>
        <valid-to>2099-07-13T00:00:00+00:00</valid-to>
        <price-scale-entries>
          <fixed-price-entry quantity="1" unit="">
            <value>39.50</value>
          </fixed-price-entry>
        </price-scale-entries>
      </price-scale-table>
    </product-price-list-entry>
    <product-price-list-entry sku="987654321" import-mode="REPLACE">
      <price-scale-table type-code="1" currency="EUR">
        <valid-from>2021-08-05T00:00:00+00:00</valid-from>
        <valid-to>2099-12-31T00:00:00+00:00</valid-to>
        <price-scale-entries>
          <fixed-price-entry quantity="1" unit="">
            <value>25.95</value>
          </fixed-price-entry>
        </price-scale-entries>
      </price-scale-table>
      <price-scale-table type-code="1" currency="EUR">
        <valid-from>2021-07-22T00:00:00+00:00</valid-from>
        <valid-to>2099-07-22T00:00:00+00:00</valid-to>
        <price-scale-entries>
          <fixed-price-entry quantity="1" unit="">
            <value>39.95</value>
          </fixed-price-entry>
        </price-scale-entries>
      </price-scale-table>
      <price-scale-table type-code="1" currency="EUR">
        <valid-from>2021-07-06T00:00:00+00:00</valid-from>
        <valid-to>2099-07-13T00:00:00+00:00</valid-to>
        <price-scale-entries>
          <fixed-price-entry quantity="1" unit="">
            <value>44.95</value>
          </fixed-price-entry>
        </price-scale-entries>
      </price-scale-table>
    </product-price-list-entry>
  </product-price-list>
</enfinity>
michael.hor257k
  • 113,275
  • 6
  • 33
  • 51