XSLT - 将子节点分组在同一父节点下

XSLT - Group child nodes under same parent

我有以下输入XML

输入XML

<bills>
    <bill>
        <billNo>1</billNo>
        <exportType>1</exportType>
        <invoice>
            <serialNo>1</serialNo>
        </invoice>
    </bill>
    <bill>
        <billNo>1</billNo>
        <exportType>1</exportType>
        <invoice>
            <serialNo>2</serialNo>
        </invoice>
    </bill>
    <bill>
        <billNo>2</billNo>
        <exportType>1</exportType>
        <invoice>
            <serialNo>1</serialNo>
        </invoice>
    </bill>
    <bill>
        <billNo>2</billNo>
        <exportType>1</exportType>
        <invoice>
            <serialNo>2</serialNo>
        </invoice>
    </bill>
    <bill>
        <billNo>2</billNo>
        <exportType>1</exportType>
        <invoice>
            <serialNo>3</serialNo>
        </invoice>
    </bill>
</bills>

需要转换为输出XML

输出XML

<bills>
    <bill>
        <billNo>1</billNo>
        <exportType>1</exportType>
        <invoice>
            <serialNo>1</serialNo>
        </invoice>
        <invoice>
            <serialNo>2</serialNo>
        </invoice>
    </bill>
    <bill>
        <billNo>2</billNo>
        <exportType>1</exportType>
        <invoice>
            <serialNo>1</serialNo>
        </invoice>
        <invoice>
            <serialNo>2</serialNo>
        </invoice>
        <invoice>
            <serialNo>3</serialNo>
        </invoice>
    </bill>
</bills>

以下 XSLT 用于转换,但是我遗漏了一些东西,因为 bill 下的子节点也被重复复制,而不是仅 invoice 子节点及其子节点被复制。 XSL如下

XSL

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes" />
    <xsl:strip-space elements="*" />
    <xsl:key name="key" match="bill" use="billNo" />
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="bill[generate-id() = generate-id(key('key', billNo)[1])]">
        <bill>
            <xsl:apply-templates select="key('key', billNo)/*" />
        </bill>
    </xsl:template>
    <xsl:template match="bill" />
</xsl:stylesheet>

获得预期结果的一种方法是更改​​此设置:

<xsl:apply-templates select="key('key', billNo)/*" />

至:

<xsl:apply-templates select="billNo | exportType" />
<xsl:apply-templates select="key('key', billNo)/invoice" />

请注意,这假设 exportType 对于在公共 billNo 下分组的所有项目都是相同的。