【发布时间】:2010-04-20 23:40:37
【问题描述】:
我有一个这样的 xml:
<person name="foo" gender = "male" />
我想把它改成
<person id="foo" gender="male" />
有没有办法使用 XSLT 做到这一点?
我个人会有很多子节点
我将拥有更多的人属性。
【问题讨论】:
-
这看起来更像是在给我重命名一个属性,除非你的实际场景中有更多没有涉及到问题。
我有一个这样的 xml:
<person name="foo" gender = "male" />
我想把它改成
<person id="foo" gender="male" />
有没有办法使用 XSLT 做到这一点?
我个人会有很多子节点
我将拥有更多的人属性。
【问题讨论】:
这很简单:使用恒等转换并创建一个模板来转换name 属性:
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@name">
<xsl:attribute name="id">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
这将使文档中除name 属性之外的所有内容保持原样。如果您只想更改 person 元素上的 name 属性,请在模板的 match 属性中放置更严格的 XPath,例如person/@name.
【讨论】:
应该这样做,不太确定 {name()} 但您可以将其替换为 "person"
> <xsl:template match="person">
> <xsl:element name="{name()}">
> <xsl:attribute name="id">
> <xsl:value-of select="@name"/>
> </xsl:attribute>
> <xsl:attribute name="gender">
> <xsl:value-of select="@gender"/>
> </xsl:attribute>
> </xsl:element>
> </xsl:template>
【讨论】:
xsl:element,一个属性值模板和name() 函数来创建一个名字你已经知道的元素是很疯狂的。将<xsl:element> 替换为<person>,您也可以将xsl:attribute 元素替换为AVT。做所有这些,答案仍然不正确(kunjaan 的问题的答案是“不,除非你这样做”),但错误会少一些。
<xsl:copy> 而不是<xsl:element name="{name()}">。此外,您的解决方案会去除其他属性和任何子节点,而问题要求保留这些属性。