将 XML 中的 2 个兄弟元素列表重新组织为嵌套结构的有效方法

问题描述 投票:0回答:1

我有一个 XSLT 要求,如下所示

一个示例 xml 输入复制我的实际场景。

<Root>
    <List1>
        <list1Child>
            <Id>1</Id>
            <Name>Test1</Name>
        </list1Child>
        <list1Child>
            <Id>2</Id>
            <Name>Test2</Name>
        </list1Child>
    </List1>

    <List2>
        <list2Child>
            <AoId>1</AoId>
            <Department>Dep1</Department>
        </list2Child>
        <list2Child>
            <AoId>1</AoId>
            <Department>Dep11</Department>
        </list2Child>
        <list2Child>
            <AoId>2</AoId>
            <Department>Dep2</Department>
        </list2Child>
    </List2>

</Root>

在这里,我希望 List2 元素显示为列表 1 下的嵌套元素。这里 Id 和 AoId 是匹配键

下面的示例输出

<Root>
    <List1>
        <list1Child>
            <Id>1</Id>
            <Name>Test1</Name>
            <List2>
                <list2Child>
                    <AoId>1</AoId>
                    <Department>Dep1</Department>
                </list2Child>
                <list2Child>
                    <AoId>1</AoId>
                    <Department>Dep11</Department>
                </list2Child>
            </List2>
        </list1Child>
        <list1Child>
            <Id>2</Id>
            <Name>Test2</Name>
            <List2>
                <list2Child>
                    <AoId>2</AoId>
                    <Department>Dep2</Department>
                </list2Child>
            </List2>
        </list1Child>
    </List1>
</Root>

我正在使用 XSLT(版本 2),并且能够通过嵌套的 for-each 循环和谓词来做到这一点。下面提供的伪代码片段

<xsl:stylesheet version="2.0">
<xsl:template match="/">
<xsl:for-each select="/Root/List1/list1Child">

..
..
..
<xsl:for-each select="/Root/List2/list2Child [AoId=Id]">

..
..
..
</xsl:for-each>
</xsl:for-each>

</xsl:template>
</xsl:stylesheet>

但是,在某些情况下,我有一个非常大的 xml,并且此 xslt 大约需要 10 秒。我想提高性能。我认为使用按键可能会提高性能并尝试了以下

<xsl:stylesheet version="2.0">
<xsl:key name="List2Key" match="list2Child" use="AoId"/>

<xsl:template match="/">
<xsl:for-each select="/Root/List1/list1Child">

..
..
..
<xsl:for-each select="key(‘List2Key’,Id)">
..
..
..
</xsl:for-each>
</xsl:for-each>

</xsl:template>
</xsl:stylesheet>

但是上面的内容无法解析。也许密钥属于不同的节点,并且可能在第一个 for-each 节点下未被识别?我尝试使用

for-each-group
和 Muenchian 方法。但是无法使其工作。是否有其他更有效的方法来实现这种嵌套结构。感谢任何有效解决方案的指示。

xslt-1.0 xslt-2.0 soa
1个回答
0
投票

我无法重现您使用密钥报告的问题。我相信我使用以下方法得到了预期的结果:

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

<xsl:key name="List2Key" match="list2Child" use="AoId"/>

<xsl:template match="/Root">
    <xsl:copy>
        <List1>
            <xsl:for-each select="List1/list1Child">
                <xsl:copy>
                    <xsl:copy-of select="*"/>
                    <List2>
                        <xsl:copy-of select="key('List2Key', Id)"/>
                    </List2>
                </xsl:copy>
            </xsl:for-each>
        </List1>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

是否更高效取决于所使用的处理器。

© www.soinside.com 2019 - 2024. All rights reserved.