问题 如何使用XSLT重命名属性?


我有一个像这样的xml:

<person name="foo" gender = "male" />

我想把它改造成

<person id="foo" gender="male" />

有没有办法使用XSLT做到这一点?

  • 我会亲自拥有很多子节点

  • 我会在这个人身上拥有更多属性。


7009
2018-04-20 23:40


起源

这看起来更像是将属性重命名给我,除非你的实际场景没有更多的问题。 - Pavel Minaev


答案:


这很简单:使用身份转换并创建一个转换的模板 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 属性完全一样。如果你只想改变 name 属性 person 元素,在模板中添加更严格的XPath match 属性,例如 person/@name


14
2018-04-21 04:24



简洁,干净,简单。很好的答案。 - markusk
工作得很漂亮。 - unj2


这应该这样做,不完全确定{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>

-1
2018-04-21 00:01



我是否需要为每个属性创建一个属性?我可以复制除id之外的所有属性吗? - unj2
使用起来很疯狂 xsl:element,属性值模板和 name() 用于创建您已知道其名称的元素的函数。更换 <xsl:element> 同 <person> 你也可以替换 xsl:attribute AVT的元素。做所有这些,答案仍然是不对的(kunjaan的问题的答案是“不,除非你这样做”),但这样做不会错。 - Robert Rossney
只是尝试提供一个适用于任何元素的通用解决方案,无论名称如何。如果它只适用于<person>元素,那么当然更简单的硬编码解决方案会更好。 - derek
如果您想避免硬编码名称,请使用 <xsl:copy> 代替 <xsl:element name="{name()}">。此外,您的解决方案会剥离其他属性和任何子节点,而问题则要求保留这些属性。 - markusk
@markusk:问题没有 本来 说根本就存在其他属性和子节点。在原始问题发布后约5小时内添加了该位。 - Greg Hewgill