XSLT 保留元素的当前内容,然后附加来自另一个元素的副本

XSLT Keep current contents of element then append with copy from another element

我希望保留一个元素的当前内容,并将另一个元素的内容附加到它。输入 XML 将如下所示:

<root>
    <existingContent>
        <elements id="x">
        <element>
            <elementA>John</elementA>
            <elementB>Doe</elementB>
        </element>
            <element>
                <elementA>Jane</elementA>
                <elementB>Doe</elementB>
            </element>
        </elements>
    </existingContent>
    <temp id="y">
        <element>
            <elementA>Joe</elementA>
            <elementB>Bloggs</elementB>
        </element>
    </temp>
</root>

所需的输出如下:

<root>
    <existingContent>
        <elements id="x">
            <element>
                <elementA>John</elementA>
                <elementB>Doe</elementB>
            </element>
            <element>
                <elementA>Jane</elementA>
                <elementB>Doe</elementB>
            </element>
        </elements>
        <elements id="y">
            <element>
                <elementA>Joe</elementA>
                <elementB>Bloggs</elementB>
            </element>
        </elements>
    </existingContent>
</root>

使用以下 XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="/root/existingContent">
        <xsl:if test="./*">
            <xsl:copy-of select="."/>
            <xsl:copy>
                <xsl:element name="elements">
                    <xsl:attribute name="id">
                        <xsl:value-of select="/root/temp/@id"/>
                    </xsl:attribute>
                    <xsl:copy-of select="/root/temp/node()"/>
                </xsl:element>
            </xsl:copy>
        </xsl:if>
    </xsl:template>
    <xsl:template match="/root/temp"/>
</xsl:stylesheet>

但取而代之的是 - 当我希望将内容复制为 :

的另一个子元素时,重复父元素
<root>
   <existingContent>
      <elements id="x">
         <element>
            <elementA>John</elementA>
            <elementB>Doe</elementB>
         </element>
         <element>
            <elementA>Jane</elementA>
            <elementB>Doe</elementB>
         </element>
      </elements>
   </existingContent>
   <existingContent>
      <elements id="y">
         <element>
            <elementA>Joe</elementA>
            <elementB>Bloggs</elementB>
         </element>
      </elements>
   </existingContent>
</root>

我会使用三个模板(当然还有身份转换模板):

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

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

  <xsl:template match="root">
    <xsl:copy>
      <xsl:apply-templates select="node()[not(self::temp)]"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="existingContent">
    <xsl:copy>
      <xsl:apply-templates select="@* | node() | ../temp"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="temp">
    <elements>
      <xsl:apply-templates select="@* | node()"/>
    </elements>
  </xsl:template>

</xsl:stylesheet>

基本模板,身份转换模板,逐层递归复制所有内容,这样您就可以为要更改的节点添加模板。

在您的情况下,在 root 级别,您不想 copy/process 所有子节点,而是排除 temp 元素。

对于 existingContent,您想要添加来自父级的 temp 元素,因此您需要将 to/select 它们作为内容进行处理。

最后,您似乎不想复制 temp 元素,而是将它们转换为 elements 元素,因此匹配 temp 的模板会这样做。