与元素名称替换重复的属性值
问题描述:
假设我有以下XML:与元素名称替换重复的属性值
<element1 title="title1">
<element2 title="title2">
<element3 title="title1">
这里属性标题被复制的element1
和element3
。我想找到所有重复的元素title
,并用元素名称替换title
值。所以,上面的例子是:
<element1 title="element1">
<element2 title="title2">
<element3 title="element3">
XSLT 1.0怎么可能?
答
一,这一转变:
<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:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"@title[. = ../preceding::*/@title
or
. = ../following::*/@title
]">
<xsl:attribute name="title"><xsl:value-of select="name(..)"/></xsl:attribute>
</xsl:template>
</xsl:stylesheet>
当下面的XML文档应用:
<t>
<element1 title="title1"/>
<element2 title="title2"/>
<element3 title="title1"/>
</t>
产生想要的,正确的结果:
<t>
<element1 title="element1"/>
<element2 title="title2"/>
<element3 title="element3"/>
</t>
二,一个可能更有效的解决方案使用的密钥:
<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:key name="kTitleVyVal" match="@title" use="."/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"@title[key('kTitleVyVal', .)[2]]">
<xsl:attribute name="title"><xsl:value-of select="name(..)"/></xsl:attribute>
</xsl:template>
</xsl:stylesheet>
感谢一个非常快的答案! – Egor4eg 2012-07-25 13:11:02
@ Egor4eg:不客气。 – 2012-07-25 13:20:20