如何在不丢失兄弟数据的情况下基于子组复制 XML

How Do I Duplicate XML based on Child Groups without losing Sibling Data

(XSLT 2.0) 我正在尝试获取一条记录,并根据特定子元素的分组值将其拆分为多个记录 - 但我需要保留所有其他元素,例如:

样本XML

   <?xml version="1.0" encoding="UTF-8"?>
    <Report>
        <Record>
            <Name>Testing</Name>
            <Due_Date>2021-10-08</Due_Date>
            <Customer>
                <Name>Test Customer</Name>
                <State>GA</State>
            </Customer>
            <To_Transaction>
                <Contact name="John Smith">
                    <ID>12345</ID>
                </Contact>
                <Contact_Email>john@test.com</Contact_Email>
                <Amount>100.00</Amount>
            </To_Transaction>
            <To_Transaction>
                <Contact name="John Smith">
                    <ID>12345</ID>
                </Contact>
                <Contact_Email>john@test.com</Contact_Email>
                <Amount>150.00</Amount>
            </To_Transaction>
            <To_Transaction>
                <Contact name="Jane Doe">
                    <ID>54321</ID>
                </Contact>
                <Contact_Email>jane@test.com</Contact_Email>
                <Amount>100.00</Amount>
            </To_Transaction>
            <From_Transaction>
                <Contact name="John Smith">
                    <ID>12345</ID>
                </Contact>
                <Contact_Email>john@test.com</Contact_Email>
                <Amount>8.00</Amount>
            </From_Transaction>
            <From_Transaction>
                <Contact name="Jane Doe">
                    <ID>54321</ID>
                </Contact>
                <Contact_Email>jane@test.com</Contact_Email>
                <Amount>75.00</Amount>
            </From_Transaction>
            <From_Transaction>
                <Contact name="Jane Doe">
                    <ID>54321</ID>
                </Contact>
                <Contact_Email>jane@test.com</Contact_Email>
                <Amount>50.00</Amount>
            </From_Transaction>
        </Record>
    </Report>

成为... 预期结果

<Report>
    <Record>
        <Name>Testing</Name>
        <Due_Date>2021-10-08</Due_Date>
        <Customer>
            <Name>Test Customer</Name>
            <State>GA</State>
        </Customer>
        <To_Transaction>
            <Contact name="John Smith">
                <ID>12345</ID>
            </Contact>
            <Contact_Email>john@test.com</Contact_Email>
            <Amount>100.00</Amount>
        </To_Transaction>
        <To_Transaction>
            <Contact name="John Smith">
                <ID>12345</ID>
            </Contact>
            <Contact_Email>john@test.com</Contact_Email>
            <Amount>150.00</Amount>
        </To_Transaction>
        <From_Transaction>
            <Contact name="John Smith">
                <ID>12345</ID>
            </Contact>
            <Contact_Email>john@test.com</Contact_Email>
            <Amount>8.00</Amount>
        </From_Transaction>
    </Record>
    <Record>
        <Name>Testing</Name>
        <Due_Date>2021-10-08</Due_Date>
        <Customer>
            <Name>Test Customer</Name>
            <State>GA</State>
        </Customer>
        <To_Transaction>
            <Contact name="Jane Doe">
                <ID>54321</ID>
            </Contact>
            <Contact_Email>jane@test.com</Contact_Email>
            <Amount>100.00</Amount>
        </To_Transaction>
        <From_Transaction>
            <Contact name="Jane Doe">
                <ID>54321</ID>
            </Contact>
            <Contact_Email>jane@test.com</Contact_Email>
            <Amount>75.00</Amount>
        </From_Transaction>
        <From_Transaction>
            <Contact name="Jane Doe">
                <ID>54321</ID>
            </Contact>
            <Contact_Email>jane@test.com</Contact_Email>
            <Amount>50.00</Amount>
        </From_Transaction>
    </Record>
</Report>

理想情况下,我将按 Contact @name 属性对事务元素进行分组。到目前为止我得到的最接近的在下面。我试过身份模板,但不知道如何让它与分组一起工作:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:template match="/*">
        <Report>
            <xsl:for-each-group select="Record" group-by="(To_Transaction,'*')">
                <Record>
                    <xsl:copy-of select="."/>                  
                    </Record>
                </xsl:for-each-group>
        </Report>
    </xsl:template>
        
</xsl:stylesheet>

AFAICT,你想做:

XSLT 2.0

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

<xsl:template match="/Report">
    <xsl:copy>
        <xsl:for-each-group select="Record/(To_Transaction | From_Transaction)" group-by="Contact/ID">
            <Record>
                <xsl:copy-of select="../(Name | Due_Date | Customer)"/>
                <xsl:copy-of select="current-group()"/>
            </Record>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

或者,如果您愿意:

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

<xsl:template match="/Report">
    <xsl:copy>
        <xsl:for-each-group select="Record/(To_Transaction | From_Transaction)" group-by="Contact/ID">
            <Record>
                <xsl:copy-of select="../(* except(To_Transaction | From_Transaction))"/>
                <xsl:copy-of select="current-group()"/>
            </Record>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>