将 Muenchian 分组应用于 XSLT

Posted

技术标签:

【中文标题】将 Muenchian 分组应用于 XSLT【英文标题】:Applying Muenchian grouping to XSLT 【发布时间】:2021-11-04 11:38:52 【问题描述】:

对 xlst 完全陌生,我尝试通过许多链接来应用 Muenchian 分组但无济于事,很可能是因为我可能没有将多余的行放在正确的位置,并且不知道如何转换为xlst2 以使用 for-each-group 代替。无论如何,我要转换的 csv 文件非常简单:

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

或XML格式:

<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>

我已使用 BizTalk 生成我的平面文件源架构:

<?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>

XML 目标架构是这样的:

<?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>

我的 XML 的当前输出现在看起来像这样:

<?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>

但我想按 sku 分组,所以每个 sku 在 product-price-list-entry 中只出现一次,所以它看起来像这样:

<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>

目前将 csv 转换为 xml 的 xlst 就是这个,这是我想要修改的。我已经删除了我尝试添加的内容,因为它不起作用:(

<?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>

【问题讨论】:

请编辑您的问题并添加输入 XML。 您当然应该考虑改用 XSLT 2.0。您在什么平台/环境中运行? 嗨@MichaelKay,我不是 XSLT 程序员,所以可能有更好的工具,但我只是使用 BizTalk 生成仅适用于 1.0 的 XSL,尤其是当 csv 和 xml文件都非常简单(或者至少我认为)。我确实在网上快速浏览了一下,看看是否可以将其转换为 XSLT 2.0,但看起来它是有成本的,并且需要更广泛的 XSLT 语言技能。 嗨@michael.hor257k,刚刚更新了CSV格式的输入文件,希望你能帮忙。提前致谢。 XSL 转换的输入是 XML,而不是 CSV(至少在 XSLT 1.0 中不是)。显然,您正在使用一些将 CSV 转换为 XML 并将其作为 XSLT 处理器的输入的应用程序。我们需要查看原始 XML。尝试使用仅包含 identity transform 的样式表来获取它。当您使用它时,了解正在使用的处理器也可能会有所帮助 - 在这里查看如何获得它:***.com/a/25245033/3016153 【参考方案1】:

让我从与您的问题无关但仍与主题相关的内容开始,恕我直言:您当前的样式表过于冗长。正如 cmets 中所指出的,使用 attribute value templates 而不是 xsl:attribute 指令可以显着减少它。此外,第一个模板完全是多余的,因为这是由built-in template rules 处理的。还有其他一些事情。我冒昧地删除了所有不必要的冗长。

除此之外,这是Muenchian grouping 的一个非常标准的实现——不知道你为什么会遇到这样的问题:

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>

应用于您的输入示例,这将生成:

结果

<?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>

【讨论】:

以上是关于将 Muenchian 分组应用于 XSLT的主要内容,如果未能解决你的问题,请参考以下文章

Muenchian 分组 XSLT 1.0 多重分组

XSLT:如何使用 Muenchian 分组将 XML 转换为文本文件

XSLT muenchian 在子节点中按值分组

使用 XSLT 对 HTML 输出进行分组(muenchian 分组?)

XSLT 和 Muenchian 分组, 多级样本

我无法理解 XSLT 1.0 Muenchian 分组