我想将特定元素(本例中为父元素)的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>
我一直在搞乱上面但我仍然无法按照我想要的方式得到它。提前谢谢。
答案 0 :(得分:6)
您不是要为所有属性或仅 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>