Select XML 使用 XSLT 基于 ID 来自多个 xPath 的节点

Select XML Node from multiple xPath based on ID using XSLT

我目前正在执行一项任务,我需要循环遍历 XML 文件的两个不同部分(两个文件之前合并到这个文件中)并搜索 ID。

如果 ID、颜色和数量值在文件的两个位置都匹配,我需要 select 第二个文件 (fileB) 中的所有字段。

如果没有,那么我需要 select 第一个文件 (fileA) 中的字段。

这是 XML 的示例:

<root>
  <fileA>
    <data>
        <id>123</id>
        <color>Green</color>
        <quantaties>5</quantaties>
    </data>
    <data>
        <id>456</id>
        <color>Red</color>
        <quantaties>7</quantaties>
    </data>
    <data>
        <id>789</id>
        <color>Blue</color>
        <quantaties>9</quantaties>
    </data>
  </fileA>
  <fileB>
    <data>
        <id>456</id>
        <color>Red</color>
        <quantaties>7</quantaties>
        <date>15-07-2021</date>
        <reason>Internal</reason>
    </data>
  </fileB>
</root>

在上面的例子中,只有 id 456,颜色为红色,数量为 7,出现在两个文件中。在这种情况下,我想从文件 B 中填充那个文件。所以我想要的输出是:

<root>
  <newFile>
    <data>
        <id>123</id>
        <color>Green</color>
        <quantaties>5</quantaties>
    </data>
    <data>
        <id>456</id>
        <color>Red</color>
        <quantaties>7</quantaties>
        <date>15-07-2021</date>
        <reason>Internal</reason>
    </data>
    <data>
        <id>789</id>
        <color>Blue</color>
        <quantaties>9</quantaties>
    </data>
  </newFile>
</root>

请记住,多个字段必须匹配,不仅仅是 ID。还有颜色和数量,以便选择 fileB 数据。谁能帮我解决这个问题?挣扎了一段时间

我会这样做:

XSLT 3.0

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

<xsl:key name="fileB" match="fileB/data" use="id||color||quantaties"/>

<xsl:template match="/root">
    <xsl:copy>
        <newFile>
            <xsl:for-each select="fileA/data">
                <xsl:copy>
                    <xsl:copy-of select="*, key('fileB', id||color||quantaties)/(* except (id|color|quantaties))"/>
                </xsl:copy>
            </xsl:for-each>
        </newFile>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

请注意,这假设 color 不以数字开头或结尾 - 否则您应该在 key 值中插入分隔符。


或者你可以这样做:

<xsl:stylesheet version="3.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="/root">
    <xsl:copy>
        <newFile>
            <xsl:for-each-group select="*/data" group-by="id, color, quantaties" composite="yes">
                <xsl:copy>
                    <xsl:for-each-group select="current-group()/*" group-by="name()" >
                        <xsl:copy-of select="."/>
                    </xsl:for-each-group>
                </xsl:copy>
            </xsl:for-each-group>
        </newFile>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>