我有一个像这样的XML元素:
<element addr="::" value="1">
现在,如果value
为"0"
,我想将addr
的值更改为"::"
。
对我来说,一个合乎逻辑的解决方案是这样的:
<xsl:template match="element/@*">
<xsl:if test="@addr = '::'">
<xsl:message>Matched</xsl:message>
<xsl:attribute name="value">0</xsl:attribute>
</xsl:if>
<xsl:copy>
<xsl:apply-templates select="node()" />
</xsl:copy>
</xsl:template>
但这似乎不起作用。
我怎么能纠正这个?
答案 0 :(得分:4)
使用复制所有内容的身份模板:
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
并使用修改您要修改的内容的模板规则覆盖它:
<xsl:template match="@value[../@addr = '::']">
<xsl:attribute name="value">0</xsl:attribute>
</xsl:template>
答案 1 :(得分:1)
您尝试无效的原因是您的模板与"element/@*"
匹配,即element
的每个属性。在该上下文中,条件<xsl:if test="@addr = '::'">
将永远不会返回true,因为这两个属性都没有(或可以拥有)名为addr
的子属性。
要仅修改value
属性,请将模板明确地与其匹配,或者:
<xsl:template match="@value">
或 - 如果您有其他具有名为value
的属性的元素,并且您希望确保将其排除在外: -
<xsl:template match="element/@value">
然后您可以通过以下方式有条件地替换它(
)<xsl:choose>
<xsl:when test="../@addr = '::'">
<xsl:attribute name="value">0</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:copy/>
</xsl:otherwise>
</xsl:choose>
或者,你可以这样做:
<xsl:template match="element[@value and @addr = '::']">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="value">0</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
即。匹配具有需要更改的属性的元素并覆盖该属性。
请注意,我们假设您还有一个身份转换模板。