XSLT Muenchian 分组来自 BizTalk WCF-SQL Adapter Schema by ID across groups

XSLT Muenchian grouping from BizTalk WCF-SQL Adapter Schema by ID across groups

我正在开发一个 BizTalk 应用程序,该应用程序使用 WCF SQL 适配器从数据库执行类型化轮询。在研究了如何将生成的模式中的数据分组到我的规范模式之后,我发现 Muenchian Grouping 是常见的解决方案。但是,我很难弄清楚如何将它应用到我的情况中。

基本上,我正在轮询的数据分布在多个表中,这些表混合了一对一和一对多关系,这些关系在所有表中共享相同的主键。由于一对多关系,我无法使用单个 SELECT 语句从各个表中提取所有数据,而是选择在我的轮询数据语句中将其拆分为 生成了下图中显示的源模式。

我想做的只是通过 "SharedID" 将所有记录从我的源模式中分离出来,并将它们放入目标模式中的适当记录中。 (我也有子组的辅助实例编号 ID,但我想这些将以相同的方式解决。)我看到的所有示例都展示了当 XSLT 密钥派生自 single node or multiple nodes 时如何执行此操作来自源模式,但它们没有显示如何解释同一 ID 何时来自多个节点。

我已经尽我所能分析了来自许多来源的示例,但我对 XSLT 还是个新手,所以我很难弄清楚如何设置我的键和 for-each 语句以适应这种方法。任何帮助揭开我应该如何去做的神秘面纱将不胜感激。谢谢!

这是使用我的源和目标模式结构的通用版本的地图的屏幕截图。

这是上面的地图生成的 XSLT,我将其用作起点。

<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
                exclude-result-prefixes="msxsl var s0"
                version="1.0"
                xmlns:s0="http://SmallGenericSchemaTest.Schemas/SourceSchema"
                xmlns:ns0="http://SmallGenericSchemaTest.Schemas/DestinationSchema">
    <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />

    <xsl:template match="/">
        <xsl:apply-templates select="/s0:TypedPolling" />
    </xsl:template>

    <xsl:template match="/s0:TypedPolling">
        <ns0:AllRecords>
            <ns0:SingleRecord>
                <xsl:for-each select="s0:TypedPollingResultSet0">
                    <xsl:for-each select="s0:TypedPollingResultSet0">
                        <ns0:GroupA>
                            <xsl:if test="s0:SharedID">
                                <ns0:SharedID>
                                    <xsl:value-of select="s0:SharedID/text()" />
                                </ns0:SharedID>
                            </xsl:if>

                            <xsl:if test="s0:MiscInfoA1">
                                <ns0:MiscInfoA1>
                                    <xsl:value-of select="s0:MiscInfoA1/text()" />
                                </ns0:MiscInfoA1>
                            </xsl:if>

                            <xsl:if test="s0:MiscInfoA2">
                                <ns0:MiscInfoA2>
                                    <xsl:value-of select="s0:MiscInfoA2/text()" />
                                </ns0:MiscInfoA2>
                            </xsl:if>
                        </ns0:GroupA>
                    </xsl:for-each>
                </xsl:for-each>

                <xsl:for-each select="s0:TypedPollingResultSet1">
                    <xsl:for-each select="s0:TypedPollingResultSet1">
                        <ns0:GroupB>
                            <xsl:if test="s0:MiscInfoB1">
                                <ns0:MiscInfoB1>
                                    <xsl:value-of select="s0:MiscInfoB1/text()" />
                                </ns0:MiscInfoB1>
                            </xsl:if>

                            <xsl:if test="s0:MiscInfoB2">
                                <ns0:MiscInfoB2>
                                    <xsl:value-of select="s0:MiscInfoB2/text()" />
                                </ns0:MiscInfoB2>
                            </xsl:if>

                            <ns0:SubGroupBAContainer>
                                <xsl:for-each select="../../s0:TypedPollingResultSet2">
                                    <xsl:for-each select="s0:TypedPollingResultSet2">
                                        <ns0:SubGroupBA>
                                            <xsl:if test="s0:MiscInfoBA1">
                                                <ns0:MiscInfoBA1>
                                                    <xsl:value-of select="s0:MiscInfoBA1/text()" />
                                                </ns0:MiscInfoBA1>
                                            </xsl:if>

                                            <xsl:if test="s0:MiscInfoBA2">
                                                <ns0:MiscInfoBA2>
                                                    <xsl:value-of select="s0:MiscInfoBA2/text()" />
                                                </ns0:MiscInfoBA2>
                                            </xsl:if>
                                        </ns0:SubGroupBA>
                                    </xsl:for-each>
                                </xsl:for-each>
                            </ns0:SubGroupBAContainer>

                            <ns0:SubGroupBBContainer>
                                <xsl:for-each select="../../s0:TypedPollingResultSet3">
                                    <xsl:for-each select="s0:TypedPollingResultSet3">
                                        <ns0:SubGroupBB>
                                            <xsl:if test="s0:MiscInfoBB1">
                                                <ns0:MiscInfoBB1>
                                                    <xsl:value-of select="s0:MiscInfoBB1/text()" />
                                                </ns0:MiscInfoBB1>
                                            </xsl:if>

                                            <xsl:if test="s0:MiscInfoBB2">
                                                <ns0:MiscInfoBB2>
                                                    <xsl:value-of select="s0:MiscInfoBB2/text()" />
                                                </ns0:MiscInfoBB2>
                                            </xsl:if>
                                        </ns0:SubGroupBB>
                                    </xsl:for-each>
                                </xsl:for-each>
                            </ns0:SubGroupBBContainer>
                        </ns0:GroupB>
                    </xsl:for-each>
                </xsl:for-each>

                <ns0:GroupCContainer>
                    <xsl:for-each select="s0:TypedPollingResultSet4">
                        <xsl:for-each select="s0:TypedPollingResultSet4">
                            <ns0:GroupC>
                                <xsl:if test="s0:GroupCInstanceID">
                                    <ns0:GroupCInstanceID>
                                        <xsl:value-of select="s0:GroupCInstanceID/text()" />
                                    </ns0:GroupCInstanceID>
                                </xsl:if>

                                <xsl:if test="s0:MiscInfoC1">
                                    <ns0:MiscInfoC1>
                                        <xsl:value-of select="s0:MiscInfoC1/text()" />
                                    </ns0:MiscInfoC1>
                                </xsl:if>

                                <xsl:if test="s0:MiscInfoC2">
                                    <ns0:MiscInfoC2>
                                        <xsl:value-of select="s0:MiscInfoC2/text()" />
                                    </ns0:MiscInfoC2>
                                </xsl:if>
                            </ns0:GroupC>
                        </xsl:for-each>
                    </xsl:for-each>
                </ns0:GroupCContainer>

                <ns0:GroupDContainer>
                    <xsl:for-each select="s0:TypedPollingResultSet5">
                        <xsl:for-each select="s0:TypedPollingResultSet5">
                            <ns0:GroupD>
                                <xsl:if test="s0:GroupDInstanceID">
                                    <ns0:GroupDInstanceID>
                                        <xsl:value-of select="s0:GroupDInstanceID/text()" />
                                    </ns0:GroupDInstanceID>
                                </xsl:if>

                                <xsl:if test="s0:MiscInfoD1">
                                    <ns0:MiscInfoD1>
                                        <xsl:value-of select="s0:MiscInfoD1/text()" />
                                    </ns0:MiscInfoD1>
                                </xsl:if>

                                <xsl:if test="s0:MiscInfoD2">
                                    <ns0:MiscInfoD2>
                                        <xsl:value-of select="s0:MiscInfoD2/text()" />
                                    </ns0:MiscInfoD2>
                                </xsl:if>
                                <xsl:for-each select="../../s0:TypedPollingResultSet6">
                                    <xsl:for-each select="s0:TypedPollingResultSet6">
                                        <ns0:SubGroupDA>
                                            <xsl:if test="s0:MiscInfoDA1">
                                                <ns0:MiscInfoDA1>
                                                    <xsl:value-of select="s0:MiscInfoDA1/text()" />
                                                </ns0:MiscInfoDA1>
                                            </xsl:if>

                                            <xsl:if test="s0:MiscInfoDA2">
                                                <ns0:MiscInfoDA2>
                                                    <xsl:value-of select="s0:MiscInfoDA2/text()" />
                                                </ns0:MiscInfoDA2>
                                            </xsl:if>
                                        </ns0:SubGroupDA>
                                    </xsl:for-each>
                                </xsl:for-each>

                                <ns0:SubGroupDBContainer>
                                    <xsl:for-each select="../../s0:TypedPollingResultSet7">
                                        <xsl:for-each select="s0:TypedPollingResultSet7">
                                            <ns0:SubGroupDB>
                                                <xsl:if test="s0:MiscInfoDB1">
                                                    <ns0:MiscInfoDB1>
                                                        <xsl:value-of select="s0:MiscInfoDB1/text()" />
                                                    </ns0:MiscInfoDB1>
                                                </xsl:if>

                                                <xsl:if test="s0:MiscInfoDB2">
                                                    <ns0:MiscInfoDB2>
                                                        <xsl:value-of select="s0:MiscInfoDB2/text()" />
                                                    </ns0:MiscInfoDB2>
                                                </xsl:if>
                                            </ns0:SubGroupDB>
                                        </xsl:for-each>
                                    </xsl:for-each>
                                </ns0:SubGroupDBContainer>
                            </ns0:GroupD>
                        </xsl:for-each>
                    </xsl:for-each>
                </ns0:GroupDContainer>
            </ns0:SingleRecord>
        </ns0:AllRecords>
    </xsl:template>
</xsl:stylesheet>

编辑:

这是一个示例输入 xml 文档和所需的输出。

示例输入:

<ns0:TypedPolling xmlns:ns0="http://SmallGenericSchemaTest.Schemas/SourceSchema">
    <ns0:TypedPollingResultSet0>
        <ns0:TypedPollingResultSet0>
            <ns0:SharedID>SharedID_1</ns0:SharedID>
            <ns0:MiscInfoA1>A1_1</ns0:MiscInfoA1>
            <ns0:MiscInfoA2>A2_1</ns0:MiscInfoA2>
        </ns0:TypedPollingResultSet0>

        <ns0:TypedPollingResultSet0>
            <ns0:SharedID>SharedID_2</ns0:SharedID>
            <ns0:MiscInfoA1>A1_2</ns0:MiscInfoA1>
            <ns0:MiscInfoA2>A2_2</ns0:MiscInfoA2>
        </ns0:TypedPollingResultSet0>
    </ns0:TypedPollingResultSet0>

    <ns0:TypedPollingResultSet1>
        <ns0:TypedPollingResultSet1>
            <ns0:SharedID>SharedID_1</ns0:SharedID>
            <ns0:MiscInfoB1>B1_1</ns0:MiscInfoB1>
            <ns0:MiscInfoB2>B2_1</ns0:MiscInfoB2>
        </ns0:TypedPollingResultSet1>

        <ns0:TypedPollingResultSet1>
            <ns0:SharedID>SharedID_2</ns0:SharedID>
            <ns0:MiscInfoB1>B1_2</ns0:MiscInfoB1>
            <ns0:MiscInfoB2>B2_2</ns0:MiscInfoB2>
        </ns0:TypedPollingResultSet1>
    </ns0:TypedPollingResultSet1>

    <ns0:TypedPollingResultSet2>
        <ns0:TypedPollingResultSet2>
            <ns0:SharedID>SharedID_1</ns0:SharedID>
            <ns0:MiscInfoBA1>BA1_1A</ns0:MiscInfoBA1>
            <ns0:MiscInfoBA2>BA2_1A</ns0:MiscInfoBA2>
        </ns0:TypedPollingResultSet2>

        <ns0:TypedPollingResultSet2>
            <ns0:SharedID>SharedID_1</ns0:SharedID>
            <ns0:MiscInfoBA1>BA1_1B</ns0:MiscInfoBA1>
            <ns0:MiscInfoBA2>BA2_1B</ns0:MiscInfoBA2>
        </ns0:TypedPollingResultSet2>

        <ns0:TypedPollingResultSet2>
            <ns0:SharedID>SharedID_2</ns0:SharedID>
            <ns0:MiscInfoBA1>BA1_2A</ns0:MiscInfoBA1>
            <ns0:MiscInfoBA2>BA2_2A</ns0:MiscInfoBA2>
        </ns0:TypedPollingResultSet2>

        <ns0:TypedPollingResultSet2>
            <ns0:SharedID>SharedID_2</ns0:SharedID>
            <ns0:MiscInfoBA1>BA1_2B</ns0:MiscInfoBA1>
            <ns0:MiscInfoBA2>BA2_2B</ns0:MiscInfoBA2>
        </ns0:TypedPollingResultSet2>
    </ns0:TypedPollingResultSet2>

    <ns0:TypedPollingResultSet3>
        <ns0:TypedPollingResultSet3>
            <ns0:SharedID>SharedID_1</ns0:SharedID>
            <ns0:MiscInfoBB1>BB1_1A</ns0:MiscInfoBB1>
            <ns0:MiscInfoBB2>BB2_1A</ns0:MiscInfoBB2>
        </ns0:TypedPollingResultSet3>

        <ns0:TypedPollingResultSet3>
            <ns0:SharedID>SharedID_1</ns0:SharedID>
            <ns0:MiscInfoBB1>BB1_1B</ns0:MiscInfoBB1>
            <ns0:MiscInfoBB2>BB2_1B</ns0:MiscInfoBB2>
        </ns0:TypedPollingResultSet3>

        <ns0:TypedPollingResultSet3>
            <ns0:SharedID>SharedID_2</ns0:SharedID>
            <ns0:MiscInfoBB1>BB1_2</ns0:MiscInfoBB1>
            <ns0:MiscInfoBB2>BB2_2</ns0:MiscInfoBB2>
        </ns0:TypedPollingResultSet3>
    </ns0:TypedPollingResultSet3>

    <ns0:TypedPollingResultSet4>
        <ns0:TypedPollingResultSet4>
            <ns0:SharedID>SharedID_1</ns0:SharedID>
            <ns0:GroupCInstanceID>GroupCInstanceID_1A</ns0:GroupCInstanceID>
            <ns0:MiscInfoC1>C1_1A</ns0:MiscInfoC1>
            <ns0:MiscInfoC2>C2_1A</ns0:MiscInfoC2>
        </ns0:TypedPollingResultSet4>

        <ns0:TypedPollingResultSet4>
            <ns0:SharedID>SharedID_1</ns0:SharedID>
            <ns0:GroupCInstanceID>GroupCInstanceID_1B</ns0:GroupCInstanceID>
            <ns0:MiscInfoC1>C1_1B</ns0:MiscInfoC1>
            <ns0:MiscInfoC2>C2_1B</ns0:MiscInfoC2>
        </ns0:TypedPollingResultSet4>

        <ns0:TypedPollingResultSet4>
            <ns0:SharedID>SharedID_2</ns0:SharedID>
            <ns0:GroupCInstanceID>GroupCInstanceID_2</ns0:GroupCInstanceID>
            <ns0:MiscInfoC1>C1_2</ns0:MiscInfoC1>
            <ns0:MiscInfoC2>C2_2</ns0:MiscInfoC2>
        </ns0:TypedPollingResultSet4>
    </ns0:TypedPollingResultSet4>

    <ns0:TypedPollingResultSet5>
        <ns0:TypedPollingResultSet5>
            <ns0:SharedID>SharedID_1</ns0:SharedID>
            <ns0:GroupDInstanceID>GroupDInstanceID_1A</ns0:GroupDInstanceID>
            <ns0:MiscInfoD1>D1_1A</ns0:MiscInfoD1>
            <ns0:MiscInfoD2>D2_1A</ns0:MiscInfoD2>
        </ns0:TypedPollingResultSet5>

        <ns0:TypedPollingResultSet5>
            <ns0:SharedID>SharedID_1</ns0:SharedID>
            <ns0:GroupDInstanceID>GroupDInstanceID_1B</ns0:GroupDInstanceID>
            <ns0:MiscInfoD1>D1_1B</ns0:MiscInfoD1>
            <ns0:MiscInfoD2>D2_1B</ns0:MiscInfoD2>
        </ns0:TypedPollingResultSet5>

        <ns0:TypedPollingResultSet5>
            <ns0:SharedID>SharedID_2</ns0:SharedID>
            <ns0:GroupDInstanceID>GroupDInstanceID_2</ns0:GroupDInstanceID>
            <ns0:MiscInfoD1>D1_2</ns0:MiscInfoD1>
            <ns0:MiscInfoD2>D2_2</ns0:MiscInfoD2>
        </ns0:TypedPollingResultSet5>
    </ns0:TypedPollingResultSet5>

    <ns0:TypedPollingResultSet6>
        <ns0:TypedPollingResultSet6>
            <ns0:SharedID>SharedID_1</ns0:SharedID>
            <ns0:GroupDInstanceID>GroupDInstanceID_1A</ns0:GroupDInstanceID>
            <ns0:MiscInfoDA1>DA1_1A</ns0:MiscInfoDA1>
            <ns0:MiscInfoDA2>DA2_1A</ns0:MiscInfoDA2>
        </ns0:TypedPollingResultSet6>

        <ns0:TypedPollingResultSet6>
            <ns0:SharedID>SharedID_1</ns0:SharedID>
            <ns0:GroupDInstanceID>GroupDInstanceID_1B</ns0:GroupDInstanceID>
            <ns0:MiscInfoDA1>DA1_1B</ns0:MiscInfoDA1>
            <ns0:MiscInfoDA2>DA2_1B</ns0:MiscInfoDA2>
        </ns0:TypedPollingResultSet6>

        <ns0:TypedPollingResultSet6>
            <ns0:SharedID>SharedID_2</ns0:SharedID>
            <ns0:GroupDInstanceID>GroupDInstanceID_2</ns0:GroupDInstanceID>
            <ns0:MiscInfoDA1>DA1_2</ns0:MiscInfoDA1>
            <ns0:MiscInfoDA2>DA2_2</ns0:MiscInfoDA2>
        </ns0:TypedPollingResultSet6>
    </ns0:TypedPollingResultSet6>

    <ns0:TypedPollingResultSet7>
        <ns0:TypedPollingResultSet7>
            <ns0:SharedID>SharedID_1</ns0:SharedID>
            <ns0:GroupDInstanceID>GroupDInstanceID_1A</ns0:GroupDInstanceID>
            <ns0:MiscInfoDB1>DB1_1A</ns0:MiscInfoDB1>
            <ns0:MiscInfoDB2>DB2_1A</ns0:MiscInfoDB2>
        </ns0:TypedPollingResultSet7>

        <ns0:TypedPollingResultSet7>
            <ns0:SharedID>SharedID_1</ns0:SharedID>
            <ns0:GroupDInstanceID>GroupDInstanceID_1B</ns0:GroupDInstanceID>
            <ns0:MiscInfoDB1>DB1_1B</ns0:MiscInfoDB1>
            <ns0:MiscInfoDB2>DB2_1B</ns0:MiscInfoDB2>
        </ns0:TypedPollingResultSet7>

        <ns0:TypedPollingResultSet7>
            <ns0:SharedID>SharedID_2</ns0:SharedID>
            <ns0:GroupDInstanceID>GroupDInstanceID_2</ns0:GroupDInstanceID>
            <ns0:MiscInfoDB1>DB1_2</ns0:MiscInfoDB1>
            <ns0:MiscInfoDB2>DB2_2</ns0:MiscInfoDB2>
        </ns0:TypedPollingResultSet7>
    </ns0:TypedPollingResultSet7>
</ns0:TypedPolling>

期望的输出:

<ns0:AllRecords xmlns:ns0="http://SmallGenericSchemaTest.Schemas/DestinationSchema">
    <ns0:SingleRecord>
        <ns0:GroupA>
            <ns0:SharedID>SharedID_1</ns0:SharedID>
            <ns0:MiscInfoA1>A1_1</ns0:MiscInfoA1>
            <ns0:MiscInfoA2>A2_1</ns0:MiscInfoA2>
        </ns0:GroupA>

        <ns0:GroupB>
            <ns0:MiscInfoB1>B1_1</ns0:MiscInfoB1>
            <ns0:MiscInfoB2>B2_1</ns0:MiscInfoB2>

            <ns0:SubGroupBAContainer>
                <ns0:SubGroupBA>
                    <ns0:MiscInfoBA1>BA1_1A</ns0:MiscInfoBA1>
                    <ns0:MiscInfoBA2>BA2_1A</ns0:MiscInfoBA2>
                </ns0:SubGroupBA>

                <ns0:SubGroupBA>
                    <ns0:MiscInfoBA1>BA1_1B</ns0:MiscInfoBA1>
                    <ns0:MiscInfoBA2>BA2_1B</ns0:MiscInfoBA2>
                </ns0:SubGroupBA>
            </ns0:SubGroupBAContainer>

            <ns0:SubGroupBBContainer>
                <ns0:SubGroupBB>
                    <ns0:MiscInfoBB1>BB1_1A</ns0:MiscInfoBB1>
                    <ns0:MiscInfoBB2>BB2_1A</ns0:MiscInfoBB2>
                </ns0:SubGroupBB>

                <ns0:SubGroupBB>
                    <ns0:MiscInfoBB1>BB1_1B</ns0:MiscInfoBB1>
                    <ns0:MiscInfoBB2>BB2_1B</ns0:MiscInfoBB2>
                </ns0:SubGroupBB>
            </ns0:SubGroupBBContainer>
        </ns0:GroupB>

        <ns0:GroupCContainer>
            <ns0:GroupC>
                <ns0:GroupCInstanceID>GroupCInstanceID_1A</ns0:GroupCInstanceID>
                <ns0:MiscInfoC1>C1_1A</ns0:MiscInfoC1>
                <ns0:MiscInfoC2>C2_1A</ns0:MiscInfoC2>
            </ns0:GroupC>

            <ns0:GroupC>
                <ns0:GroupCInstanceID>GroupCInstanceID_1B</ns0:GroupCInstanceID>
                <ns0:MiscInfoC1>C1_1B</ns0:MiscInfoC1>
                <ns0:MiscInfoC2>C2_1B</ns0:MiscInfoC2>
            </ns0:GroupC>
        </ns0:GroupCContainer>

        <ns0:GroupDContainer>
            <ns0:GroupD>
                <ns0:GroupDInstanceID>GroupDInstanceID_1A</ns0:GroupDInstanceID>
                <ns0:MiscInfoD1>D1_1A</ns0:MiscInfoD1>
                <ns0:MiscInfoD2>D2_1A</ns0:MiscInfoD2>

                <ns0:SubGroupDA>
                    <ns0:MiscInfoDA1>DA1_1A</ns0:MiscInfoDA1>
                    <ns0:MiscInfoDA2>DA2_1A</ns0:MiscInfoDA2>
                </ns0:SubGroupDA>

                <ns0:SubGroupDBContainer>
                    <ns0:SubGroupDB>
                        <ns0:MiscInfoDB1>DB1_1A</ns0:MiscInfoDB1>
                        <ns0:MiscInfoDB2>DB2_1A</ns0:MiscInfoDB2>
                    </ns0:SubGroupDB>
                </ns0:SubGroupDBContainer>
            </ns0:GroupD>

            <ns0:GroupD>
                <ns0:GroupDInstanceID>GroupDInstanceID_1B</ns0:GroupDInstanceID>
                <ns0:MiscInfoD1>D1_1B</ns0:MiscInfoD1>
                <ns0:MiscInfoD2>D2_1B</ns0:MiscInfoD2>

                <ns0:SubGroupDA>
                    <ns0:MiscInfoDA1>DA1_1B</ns0:MiscInfoDA1>
                    <ns0:MiscInfoDA2>DA2_1B</ns0:MiscInfoDA2>
                </ns0:SubGroupDA>

                <ns0:SubGroupDBContainer>
                    <ns0:SubGroupDB>
                        <ns0:MiscInfoDB1>DB1_1B</ns0:MiscInfoDB1>
                        <ns0:MiscInfoDB2>DB2_1B</ns0:MiscInfoDB2>
                    </ns0:SubGroupDB>
                </ns0:SubGroupDBContainer>
            </ns0:GroupD>
        </ns0:GroupDContainer>
    </ns0:SingleRecord>

    <ns0:SingleRecord>
        <ns0:GroupA>
            <ns0:SharedID>SharedID_2</ns0:SharedID>
            <ns0:MiscInfoA1>A1_2</ns0:MiscInfoA1>
            <ns0:MiscInfoA2>A2_2</ns0:MiscInfoA2>
        </ns0:GroupA>

        <ns0:GroupB>
            <ns0:MiscInfoB1>B1_2</ns0:MiscInfoB1>
            <ns0:MiscInfoB2>B2_2</ns0:MiscInfoB2>

            <ns0:SubGroupBAContainer>
                <ns0:SubGroupBA>
                    <ns0:MiscInfoBA1>BA1_2A</ns0:MiscInfoBA1>
                    <ns0:MiscInfoBA2>BA2_2A</ns0:MiscInfoBA2>
                </ns0:SubGroupBA>

                <ns0:SubGroupBA>
                    <ns0:MiscInfoBA1>BA1_2B</ns0:MiscInfoBA1>
                    <ns0:MiscInfoBA2>BA2_2B</ns0:MiscInfoBA2>
                </ns0:SubGroupBA>
            </ns0:SubGroupBAContainer>

            <ns0:SubGroupBBContainer>
                <ns0:SubGroupBB>
                    <ns0:MiscInfoBB1>BB1_2</ns0:MiscInfoBB1>
                    <ns0:MiscInfoBB2>BB2_2</ns0:MiscInfoBB2>
                </ns0:SubGroupBB>
            </ns0:SubGroupBBContainer>
        </ns0:GroupB>

        <ns0:GroupCContainer>
            <ns0:GroupC>
                <ns0:GroupCInstanceID>GroupCInstanceID_2</ns0:GroupCInstanceID>
                <ns0:MiscInfoC1>C1_2</ns0:MiscInfoC1>
                <ns0:MiscInfoC2>C2_2</ns0:MiscInfoC2>
            </ns0:GroupC>
        </ns0:GroupCContainer>

        <ns0:GroupDContainer>
            <ns0:GroupD>
                <ns0:GroupDInstanceID>GroupDInstanceID_2</ns0:GroupDInstanceID>
                <ns0:MiscInfoD1>D1_2</ns0:MiscInfoD1>
                <ns0:MiscInfoD2>D2_2</ns0:MiscInfoD2>

                <ns0:SubGroupDA>
                    <ns0:MiscInfoDA1>DA1_2</ns0:MiscInfoDA1>
                    <ns0:MiscInfoDA2>DA2_2</ns0:MiscInfoDA2>
                </ns0:SubGroupDA>

                <ns0:SubGroupDBContainer>
                    <ns0:SubGroupDB>
                        <ns0:MiscInfoDB1>DB1_2</ns0:MiscInfoDB1>
                        <ns0:MiscInfoDB2>DB2_2</ns0:MiscInfoDB2>
                    </ns0:SubGroupDB>
                </ns0:SubGroupDBContainer>
            </ns0:GroupD>
        </ns0:GroupDContainer>
    </ns0:SingleRecord>
</ns0:AllRecords>

根据 Johns-305 的建议,我查看了 Muenchian 分组的替代方案,并得出了下面的解决方案,它似乎按预期工作。在研究了 Muenchian 方法之后,我似乎给了自己狭隘的视野。最终结果确实容易多了,但我对 XSLT 的缺乏经验使它不太明显。

当然,如果有人知道更好的方法或看到任何改进的余地,请随时提出其他建议。在接受这个答案之前,我会把这个问题开放几天,以防出现更好的答案。谢谢!

<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
                exclude-result-prefixes="msxsl var s0"
                version="1.0"
                xmlns:s0="http://SmallGenericSchemaTest.Schemas/SourceSchema"
                xmlns:ns0="http://SmallGenericSchemaTest.Schemas/DestinationSchema">
    <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />

    <xsl:template match="/">
        <xsl:apply-templates select="/s0:TypedPolling" />
    </xsl:template>

    <xsl:template match="/s0:TypedPolling">
        <ns0:AllRecords>
            <xsl:for-each select="s0:TypedPollingResultSet0/s0:TypedPollingResultSet0">
                <ns0:SingleRecord>

                    <ns0:GroupA>
                        <xsl:if test="s0:SharedID">
                            <ns0:SharedID>
                                <xsl:value-of select="s0:SharedID/text()" />
                            </ns0:SharedID>
                        </xsl:if>

                        <xsl:if test="s0:MiscInfoA1">
                            <ns0:MiscInfoA1>
                                <xsl:value-of select="s0:MiscInfoA1/text()" />
                            </ns0:MiscInfoA1>
                        </xsl:if>

                        <xsl:if test="s0:MiscInfoA2">
                            <ns0:MiscInfoA2>
                                <xsl:value-of select="s0:MiscInfoA2/text()" />
                            </ns0:MiscInfoA2>
                        </xsl:if>
                    </ns0:GroupA>


                    <xsl:for-each select="/s0:TypedPolling/s0:TypedPollingResultSet1/s0:TypedPollingResultSet1[s0:SharedID = current()/s0:SharedID]">
                        <ns0:GroupB>
                            <xsl:if test="s0:MiscInfoB1">
                                <ns0:MiscInfoB1>
                                    <xsl:value-of select="s0:MiscInfoB1/text()" />
                                </ns0:MiscInfoB1>
                            </xsl:if>

                            <xsl:if test="s0:MiscInfoB2">
                                <ns0:MiscInfoB2>
                                    <xsl:value-of select="s0:MiscInfoB2/text()" />
                                </ns0:MiscInfoB2>
                            </xsl:if>

                            <ns0:SubGroupBAContainer>
                                <xsl:for-each select="/s0:TypedPolling/s0:TypedPollingResultSet2/s0:TypedPollingResultSet2[s0:SharedID = current()/s0:SharedID]">
                                    <ns0:SubGroupBA>
                                        <xsl:if test="s0:MiscInfoBA1">
                                            <ns0:MiscInfoBA1>
                                                <xsl:value-of select="s0:MiscInfoBA1/text()" />
                                            </ns0:MiscInfoBA1>
                                        </xsl:if>

                                        <xsl:if test="s0:MiscInfoBA2">
                                            <ns0:MiscInfoBA2>
                                                <xsl:value-of select="s0:MiscInfoBA2/text()" />
                                            </ns0:MiscInfoBA2>
                                        </xsl:if>
                                    </ns0:SubGroupBA>
                                </xsl:for-each>
                            </ns0:SubGroupBAContainer>

                            <ns0:SubGroupBBContainer>
                                <xsl:for-each select="/s0:TypedPolling/s0:TypedPollingResultSet3/s0:TypedPollingResultSet3[s0:SharedID = current()/s0:SharedID]">
                                    <ns0:SubGroupBB>
                                        <xsl:if test="s0:MiscInfoBB1">
                                            <ns0:MiscInfoBB1>
                                                <xsl:value-of select="s0:MiscInfoBB1/text()" />
                                            </ns0:MiscInfoBB1>
                                        </xsl:if>

                                        <xsl:if test="s0:MiscInfoBB2">
                                            <ns0:MiscInfoBB2>
                                                <xsl:value-of select="s0:MiscInfoBB2/text()" />
                                            </ns0:MiscInfoBB2>
                                        </xsl:if>
                                    </ns0:SubGroupBB>
                                </xsl:for-each>
                            </ns0:SubGroupBBContainer>
                        </ns0:GroupB>
                    </xsl:for-each>


                    <xsl:if test="/s0:TypedPolling/s0:TypedPollingResultSet4/s0:TypedPollingResultSet4[s0:SharedID = current()/s0:SharedID]">
                        <ns0:GroupCContainer>
                            <xsl:for-each select="/s0:TypedPolling/s0:TypedPollingResultSet4/s0:TypedPollingResultSet4[s0:SharedID = current()/s0:SharedID]">
                                <ns0:GroupC>
                                    <xsl:if test="s0:GroupCInstanceID">
                                        <ns0:GroupCInstanceID>
                                            <xsl:value-of select="s0:GroupCInstanceID/text()" />
                                        </ns0:GroupCInstanceID>
                                    </xsl:if>

                                    <xsl:if test="s0:MiscInfoC1">
                                        <ns0:MiscInfoC1>
                                            <xsl:value-of select="s0:MiscInfoC1/text()" />
                                        </ns0:MiscInfoC1>
                                    </xsl:if>

                                    <xsl:if test="s0:MiscInfoC2">
                                        <ns0:MiscInfoC2>
                                            <xsl:value-of select="s0:MiscInfoC2/text()" />
                                        </ns0:MiscInfoC2>
                                    </xsl:if>
                                </ns0:GroupC>
                            </xsl:for-each>
                        </ns0:GroupCContainer>
                    </xsl:if>


                    <xsl:if test="/s0:TypedPolling/s0:TypedPollingResultSet5/s0:TypedPollingResultSet5[s0:SharedID = current()/s0:SharedID]">
                        <ns0:GroupDContainer>
                            <xsl:for-each select="/s0:TypedPolling/s0:TypedPollingResultSet5/s0:TypedPollingResultSet5[s0:SharedID = current()/s0:SharedID]">
                                <ns0:GroupD>
                                    <xsl:if test="s0:GroupDInstanceID">
                                        <ns0:GroupDInstanceID>
                                            <xsl:value-of select="s0:GroupDInstanceID/text()" />
                                        </ns0:GroupDInstanceID>
                                    </xsl:if>

                                    <xsl:if test="s0:MiscInfoD1">
                                        <ns0:MiscInfoD1>
                                            <xsl:value-of select="s0:MiscInfoD1/text()" />
                                        </ns0:MiscInfoD1>
                                    </xsl:if>

                                    <xsl:if test="s0:MiscInfoD2">
                                        <ns0:MiscInfoD2>
                                            <xsl:value-of select="s0:MiscInfoD2/text()" />
                                        </ns0:MiscInfoD2>
                                    </xsl:if>

                                    <xsl:if test="/s0:TypedPolling/s0:TypedPollingResultSet6/s0:TypedPollingResultSet6[s0:SharedID = current()/s0:SharedID]
                                            and /s0:TypedPolling/s0:TypedPollingResultSet6/s0:TypedPollingResultSet6[s0:GroupDInstanceID = current()/s0:GroupDInstanceID]">
                                        <xsl:for-each select="/s0:TypedPolling/s0:TypedPollingResultSet6/s0:TypedPollingResultSet6[s0:SharedID = current()/s0:SharedID
                                                      and s0:GroupDInstanceID = current()/s0:GroupDInstanceID]">
                                            <ns0:SubGroupDA>
                                                <xsl:if test="s0:MiscInfoDA1">
                                                    <ns0:MiscInfoDA1>
                                                        <xsl:value-of select="s0:MiscInfoDA1/text()" />
                                                    </ns0:MiscInfoDA1>
                                                </xsl:if>

                                                <xsl:if test="s0:MiscInfoDA2">
                                                    <ns0:MiscInfoDA2>
                                                        <xsl:value-of select="s0:MiscInfoDA2/text()" />
                                                    </ns0:MiscInfoDA2>
                                                </xsl:if>
                                            </ns0:SubGroupDA>
                                        </xsl:for-each>
                                    </xsl:if>

                                    <xsl:if test="/s0:TypedPolling/s0:TypedPollingResultSet7/s0:TypedPollingResultSet7[s0:SharedID = current()/s0:SharedID]
                                            and /s0:TypedPolling/s0:TypedPollingResultSet7/s0:TypedPollingResultSet7[s0:GroupDInstanceID = current()/s0:GroupDInstanceID]">
                                        <ns0:SubGroupDBContainer>
                                            <xsl:for-each select="/s0:TypedPolling/s0:TypedPollingResultSet7/s0:TypedPollingResultSet7[s0:SharedID = current()/s0:SharedID
                                                          and s0:GroupDInstanceID = current()/s0:GroupDInstanceID]">
                                                <ns0:SubGroupDB>
                                                    <xsl:if test="s0:MiscInfoDB1">
                                                        <ns0:MiscInfoDB1>
                                                            <xsl:value-of select="s0:MiscInfoDB1/text()" />
                                                        </ns0:MiscInfoDB1>
                                                    </xsl:if>

                                                    <xsl:if test="s0:MiscInfoDB2">
                                                        <ns0:MiscInfoDB2>
                                                            <xsl:value-of select="s0:MiscInfoDB2/text()" />
                                                        </ns0:MiscInfoDB2>
                                                    </xsl:if>
                                                </ns0:SubGroupDB>
                                            </xsl:for-each>
                                        </ns0:SubGroupDBContainer>
                                    </xsl:if>
                                </ns0:GroupD>
                            </xsl:for-each>
                        </ns0:GroupDContainer>
                    </xsl:if>

                </ns0:SingleRecord>
            </xsl:for-each>
        </ns0:AllRecords>
    </xsl:template>
</xsl:stylesheet>