我有一个具有特定属性(myId)的文档,只要值为零,就需要更新该值。该文件看起来像这样
<?xml version="1.0" encoding="UTF-8"?><Summary>
<Section myId="0">
<Section myId="0">
<Para>...</Para>
</Section>
<Section myId="5">
<Para>...</Para>
</Section>
</Section>
</Summary>
我使用模板匹配属性myId,以便将其设置为从调用程序传递的唯一ID,但我只想匹配文档中的一个属性。任何其他值为零的属性都将通过传递不同的ID进行更新。 我正在使用的模板如下所示:
<xsl:template match = '@myId[.="0"]'>
<xsl:attribute name = "{name()}">
<xsl:value-of select = "$addValue"/>
</xsl:attribute>
</xsl:template>
值addValue是从调用程序传递的全局参数。 我已经在当天的大部分时间里搜索了答案,但我无法仅将此模板应用一次。输出将myId值替换为addValue的内容。 我试图匹配'@myId [。“0”] [1]'并且我试图使用position()函数进行匹配,但我的模板总是应用于所有零的myId属性。 / p>
是否可以仅应用一次匹配模板?
答案 0 :(得分:1)
是否可以仅应用一次匹配模板?
是强>:
是否应用模板取决于导致选择执行模板的xsl:apply-templates
。
另外,匹配模式的确定方式可以保证模板只匹配文档中的一个特定节点。
以下是您可以做的事情:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pNewIdValue" select="9999"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"Section
[@myId = 0
and
not((preceding::Section | ancestor::Section)
[@myId = 0]
)
]/@myId">
<xsl:attribute name="myId"><xsl:value-of select="$pNewIdValue"/></xsl:attribute>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的XML文档:
<Summary>
<Section myId="0">
<Section myId="0">
<Para>...</Para>
</Section>
<Section myId="5">
<Para>...</Para>
</Section>
</Section>
</Summary>
产生了想要的正确结果:
<Summary>
<Section myId="9999">
<Section myId="0">
<Para>...</Para>
</Section>
<Section myId="5">
<Para>...</Para>
</Section>
</Section>
</Summary>