如何使用 XLS 转换复制 XML 节点并粘贴到同一级别

How to copy an XML node and paste in same level using XLS transformations

我想复制一个xml的节点并粘贴到同一层。

假设我有一个 xml,如下所示。

<MyXml>
    <system>
        <Groups>
            <Group id="01" check="true">
            <name>Value</name>
            <age>test</age>
        </Group>
        <Group id="02" check="true">
            <name>Value</name>
            <age>test</age>
        </Group>
        <Group id="03" check="true">
            <name>Value</name>
            <age>test</age>
        </Group>
        </Groups>
  </system>
</MyXml>

我想使用 XSL 转换复制组 03 并粘贴到与“04”相同的级别(组内)。

预期输出

<MyXml>
    <system>
        <Groups>
            <Group id="01" check="true">
                <name>Value</name>
                <age>test</age>
            </Group>
            <Group id="02" check="true">
                <name>Value</name>
                <age>test</age>
            </Group>
            <Group id="03" check="true">
                <name>Value</name>
                <age>test</age>
            </Group>
            <Group id="04" check="true">
                <name>Value</name>
                <age>test</age>
            </Group>
        </Groups>
  </system>
</MyXml>

有人可以帮助完成相同的 XSL 样式表吗?不确定下面的 xsl 是否正确。提前致谢。

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

<xsl:param name="groupId" />
<xsl:param name="newGroupId" />

<xsl:template match="node()|@*" name="identity">
  <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

<xsl:template match="MyXML/system/Groups/Group[@id=$groupId]" >
 <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
            <!--Wanted to do something for pasting the copied node and changing the id value with new Group Id.-->
  </xsl:copy>
</xsl:template>
</xsl:stylesheet>

在 XSLT 1.0 中,在模板匹配中使用变量表达式实际上被认为是错误的(尽管您可能会发现某些处理器允许这样做)。

但是你可能应该做的是,在模板匹配Group中调用身份模板,然后xsl:if决定是否复制它。

试试这个模板

<xsl:template match="Group" >
  <xsl:call-template name="identity" />;
  <xsl:if test="@id = $groupId">
    <group id="{$newGroupId}">
      <xsl:apply-templates select="@*[name() != 'id']|node()"/>
    </group>
  </xsl:if>
</xsl:template>

请注意,您不需要在模板匹配中找到 Group 的完整路径,除非在其他级别中有您不想匹配的 Group 元素。 (此外,您当前的匹配指的是 MyXML,而您的 XML 将其设为 MyXml。XSLT 区分大小写,因此不会匹配)。