2012-07-25 84 views
1

假设我有以下XML:与元素名称替换重复的属性值

<element1 title="title1"> 
<element2 title="title2"> 
<element3 title="title1"> 

这里属性标题被复制的element1element3。我想找到所有重复的元素title,并用元素名称替换title值。所以,上面的例子是:

<element1 title="element1"> 
<element2 title="title2"> 
<element3 title="element3"> 

XSLT 1.0怎么可能?

回答

1

一,这一转变

<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> 
+0

感谢一个非常快的答案! – Egor4eg 2012-07-25 13:11:02

+0

@ Egor4eg:不客气。 – 2012-07-25 13:20:20

相关问题