4

我想将特定元素(在这种情况下为父元素)上的 id 属性复制到父元素的子元素中的新元素中。

我的 XML 如下:

<wrapper>
    <parent id="1">
         <child>
            content
         </child>
    </parent>
</wrapper>

我需要输出是这样的:

<wrapper>
    <parent>
        <child>
            <parentid>1</parentid> 
            content
        </child>
    </parent>
</wrapper>

从下面的示例中,这个可以满足我的要求,除了它将新元素放在父元素中,而我想要在子元素中:

<xsl:template match="parent[@id]">
    <parent>
        <xsl:apply-templates select="@*[name() != 'id']" />
            <parentid>
                <xsl:value-of select="@id" />
            </parentid>
        <xsl:apply-templates select="node()"/>
    </parent>
</xsl:template>

我一直在搞乱上面的内容,但我仍然无法按照我想要的方式得到它。提前致谢。

4

1 回答 1

8

您不会说是否要对所有属性或仅id属性进行此操作,或者是否只是一个元素或所有元素的属性。

假设您想对所有元素的id属性执行此操作,但不更改其他属性。然后,您将有一个模板来匹配任何具有id属性的此类元素,如下所示:

<xsl:template match="*[@id]">

在其中,您可以根据当前元素名称创建一个新元素,如下所示:

     <xsl:element name="{name()}id">
        <xsl:value-of select="@id" />
     </xsl:element>

试试这个 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="*[@id]">
      <xsl:copy>
         <xsl:apply-templates select="@*[name() != 'id']" />
         <xsl:element name="{name()}id">
            <xsl:value-of select="@id" />
         </xsl:element>
         <xsl:apply-templates select="node()"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

请注意在动态创建新元素名称时使用属性值模板(大括号)。另请注意,您必须在创建新的子元素之前输出其他属性,因为在为其创建子元素之后输出元素的属性被认为是错误的。

当然,如果您只想要特定元素的id属性,您可以将第二个模板简化为

<xsl:template match="parent[@id]">
   <parent>
      <xsl:apply-templates select="@*[name() != 'id']" />
      <parentid>
         <xsl:value-of select="@id" />
      </parentid>
      <xsl:apply-templates select="node()"/>
   </parent>
</xsl:template>

但是,如果您想将所有属性转换为元素,则可以以完全通用的方式执行此操作,如下所示

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="@*">
      <xsl:element name="{name(..)}{name()}">
         <xsl:value-of select="." />
      </xsl:element>
   </xsl:template>
</xsl:stylesheet>

编辑:

如果要求实际上是添加id属性作为子元素的子元素,则需要进行一些调整。首先,您需要一个模板来停止在复制元素时输出父级上的id属性

<xsl:template match="parent/@id" />

然后你需要一个模板来匹配父元素的子元素

<xsl:template match="parent[@id]/*[1]">

(在这种情况下,我假设它始终是第一个子元素。如果您想要一个特定的子元素,只需在此处使用名称)

在此模板中,您可以使用父级的id属性创建新元素。

试试这个 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="parent/@id" />

   <xsl:template match="parent[@id]/*[1]">
      <xsl:copy>
         <xsl:apply-templates select="@*" />
         <parentid>
           <xsl:value-of select="../@id" />
         </parentid>
         <xsl:apply-templates select="node()"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>
于 2013-09-25T22:47:33.047 回答