在下面的代码中,我需要代替两个xxxx来获得元素的名称(name()),所以h1,h2或h3,无论匹配是什么。所以第二个xxxx必须是该文件中h1 / h2 / h3的计数。该属性将看起来像“h1_4”,或h3_15“等等。
我该怎么做?
<xsl:template match="h1[not(@id)] | h2[not(@id)] | h3[not(@id)]" >
<xsl:element name="{name()}" >
<xsl:attribute name="id">xxxx_<xsl:value-of><xsl:number count="xxxx" /></xsl:value-of></xsl:attribute>
</xsl:element>
<xsl:apply-templates/>
</xsl:template>
答案 0 :(得分:1)
正如我所说,请求含糊不清。以下样式表:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="h1[not(@id)] | h2[not(@id)] | h3[not(@id)]" >
<xsl:variable name="name" select="name()" />
<xsl:copy>
<xsl:attribute name="id">
<xsl:value-of select="$name"/>
<xsl:text>_</xsl:text>
<xsl:value-of select="count(preceding::*[name()=$name]) + 1"/>
</xsl:attribute>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
应用于以下测试输入:
<root>
<h1 id="h1_1"/>
<h2 type="abc"/>
<h3 type="xyz"/>
<h1>content</h1>
<h3 id="h3_2" type="efg"/>
<h2/>
</root>
将产生:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<h1 id="h1_1"/>
<h2 id="h2_1" type="abc"/>
<h3 id="h3_1" type="xyz"/>
<h1 id="h1_2">content</h1>
<h3 id="h3_2" type="efg"/>
<h2 id="h2_2"/>
</root>
答案 1 :(得分:0)
您使用xsl:number
走在正确的轨道上,如何:
<xsl:template match="h1 | h2 | h3" >
<xsl:copy>
<xsl:attribute name="id">
<xsl:value-of select="name()"/>
<xsl:text>_</xsl:text>
<xsl:number level="any" />
</xsl:attribute>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
我假设一个身份模板按原样复制文档的其余部分,而且我已经简化了匹配模式 - 您不需要检查{{ 1}}如果输入中有id属性,它将覆盖由not(@id)
创建的属性。