使用XSLT

时间:2015-08-20 11:02:45

标签: xml xslt xslt-2.0

我有XML:

<doc>
    <p id="123" sec="abc"></p>
</doc>

使用XSLT,我需要:

1)添加值为name

的新属性'myname'

2)复制相同的sec

3)将id属性覆盖为新值

我已经编写了以下XSLT来做到这一点,

<xsl:template match="p">
    <p name="myname" id="999">
        <xsl:apply-templates select="node()|@*"/>
    </p>
</xsl:template>

它给了我以下结果:

<doc>
   <p name="myname" id="123" sec="abc"></p>
</doc>

期望的结果是:

<doc>
   <p name="myname" id="999" sec="abc"></p>
</doc>

似乎它不会覆盖id属性值。如何从XSLT覆盖此值?

4 个答案:

答案 0 :(得分:5)

更改模板

<xsl:template match="p">
        <p name="myname" id="999">
            <xsl:apply-templates select="node()|@*"/>
        </p>
</xsl:template>

<xsl:template match="p">
        <p name="myname" id="999">
            <xsl:apply-templates select="@* except @id, node()"/>
        </p>
</xsl:template>

或为id属性编写模板:

<xsl:template match="p">
  <p name="myname">
     <xsl:apply-templates select="@* , node()"/>
  </p>
</xsl:template>

<xsl:template match="p/@id">
  <xsl:attribute name="id" select="999"/>
</xsl:template>

答案 1 :(得分:2)

我现在无法自己尝试...请尽量不要复制“ID&#39;属性,因为这会否决你的身份。 xslt中的属性。

<xsl:template match="p">
        <p name="myname" id="999">
            <xsl:apply-templates select="node()|@*[local-name() != 'id']"/>
        </p>
</xsl:template>

答案 2 :(得分:1)

或者简单地说:

pt

-

如果<xsl:template match="p"> <p name="myname" id="999" sec="{@sec}"/> </xsl:template> 元素可以包含其他节点(与显示的示例不同),请使用:

p

答案 3 :(得分:1)

关键是如果你为一个元素添加几个具有相同名称的属性,那么最后一个获胜。您的显式id =“999”被认为是在您使用xsl:apply-templates调用复制的属性之前,因此它没有任何效果。

有几种解决方案。您可以避免将模板应用于@id属性(使用apply-templates中的select);你可以有一个@id属性的模板规则,不会导致它被复制;或者你可以通过在xsl:apply-templates指令之后出现的xsl:attribute指令,在执行apply-templates之后添加id =“999”属性。