XSLT:将元素注入另一个元素

Rob*_*nho 2 xslt xslt-2.0

我需要使用id元素将xml元素注入另一个xml元素中以进行连接.

例如:

<root>
    <a>
        <id>1</id>
        <!-- other elements ... -->
    </a>
    <a>
        <id>2</id>
        <!-- other elements ... -->
    </a>
    <b>
        <id>10</id>
        <ref>1</ref>
        <!-- other elements ... -->
    </b>
    <b>
        <id>13</id>
        <ref>2</ref>
        <!-- other elements ... -->
    </b>
    <b>
        <id>13</id>
        <ref>1</ref>
        <!-- other elements ... -->
    </b>
</root>
Run Code Online (Sandbox Code Playgroud)

我需要转变为:

<root>
    <a>
        <id>1</id>
        <!-- other elements ... -->
        <b>
            <id>10</id>
            <ref>1</ref>
            <!-- other elements ... -->
        </b>
        <b>
            <id>13</id>
            <ref>1</ref>
            <!-- other elements ... -->
        </b>

    </a>
    <a>
        <id>2</id>
        <!-- other elements ... -->
        <b>
            <id>13</id>
            <ref>2</ref>
            <!-- other elements ... -->
        </b>
    </a>
</root>
Run Code Online (Sandbox Code Playgroud)

在这种情况下,当/ id等于b/ref时,我将b元素加入元素.

有可能使用XSLT进行这种转换吗?我该怎么做?

Tim*_*m C 6

首先从身份模板开始,按原样将节点复制到输出文档

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

要通过ref有效查找b元素,请考虑创建一个键:

<xsl:key name="b" match="b" use="ref" />
Run Code Online (Sandbox Code Playgroud)

然后,你可以有一个模板来匹配一个元素,在这里你既可以输出一个正常的元素,并复制相关的b元素,使用该密钥

<xsl:template match="a">
   <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
      <xsl:copy-of select="key('b', id)" />
   </xsl:copy>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

最后,您需要一个模板来阻止身份模板正常输出b元素:

<xsl:template match="b" />
Run Code Online (Sandbox Code Playgroud)

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:key name="b" match="b" use="ref" />
   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="a">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
         <xsl:copy-of select="key('b', id)" />
      </xsl:copy>
   </xsl:template>

   <xsl:template match="b" />
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)