我试图遍历我的XHTML文档中的节点,找到符合一组条件的所有节点子节点,并根据它们相对于它们在文档层次结构中的深度的位置重命名它们。
例如:
我想迭代元素中的节点,并将所有h1,h2,h3,h4,h5或h6转换为h1。
然后我想迭代元素的所有其他子元素,找到名为hN的子节点,并将它们命名为h2。
等等,通过子节点进行无限深度递归,但命名元素达到h6的限制......
这是明确的吗?请原谅,我是xsl的新手。这是我到目前为止所做的:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[contains(@class,'_col')]">
<xsl:apply-templates select="*" mode="iterate"/>
</xsl:template>
<xsl:template match="*" mode="iterate">
<xsl:if test="name()='h1' or name()='h2'or name()='h3'or name()='h4'or name()='h5'or name()='h6'">
<h6>
<xsl:apply-templates select="@*|node()"/>
</h6>
</xsl:if>
<xsl:if test="name()!='h1' and name()!='h2' and name()!='h3' and name()!='h4' and name()!='h5' and name()!='h6'">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
显然这根本不会起作用 - 如果我可以简单地让工作表输出完整的文档,并将所有h#标签转换为h1标签,那么就不会有h#标签的增量,I&#39 ;感觉还不错。任何人都可以帮忙吗?
感谢。
编辑:
第一个答案是一个很大的帮助,但要明确问题不仅仅是将所有h#标签增加一个,最多六个,它是找到所有h#标签,然后将它们设置为递增的数字,向上至六,取决于他们在doc层次结构中的深度。
这里是xml:
<?xml version="1.0" encoding="UTF-8"?>
<body>
<h2>Theme</h2>
<div class="col _incidental">
<h2>theme 2</h2>
<div>
<h3>theme 3</h3>
<p>some thext</p>
</div>
</div>
<div class="col _vital">
<h2>theme 2</h2>
<div>
<h1>theme 3</h1>
<p>some thext</p>
</div>
<h2>theme 2</h2>
<div>
<h4>theme 3</h4>
<p>some thext</p>
<h3>theme 3</h3>
<p>some thext</p>
</div>
</div>
<div class="col _related">
<h2>theme 2</h2>
</div>
<div>
<h5>theme 3</h5>
<p>some thext</p>
</div>
</div>
</div>
</body>
输出应该是:
<?xml version="1.0" encoding="UTF-8"?>
<body>
<h1>Theme</h1>
<div class="col _incidental">
<h2>theme 2</h2>
<div>
<h3>theme 3</h3>
<p>some thext</p>
</div>
</div>
<div class="col _vital">
<h2>theme 2</h2>
<div>
<h3>theme 3</h3>
<p>some thext</p>
</div>
<h2>theme 2</h2>
<div>
<h3>theme 3</h3>
<p>some thext</p>
<h3>theme 3</h3>
<p>some thext</p>
</div>
</div>
<div class="col _related">
<h2>theme 2</h2>
<div>
<div>
<h3>theme 3</h3>
<p>some thext</p>
</div>
</div>
</div>
</body>
转换包含hN元素,这些元素根据它们在doc层次结构中的位置编号,相对于找到的最后一个hN。因此,如果我找到一个h2,然后任何兄弟姐妹将被搜索,并且任何hN成为h3,如果没有找到,那么他们的兄弟姐妹会被搜查,然后他们变成h3,然后是兄弟姐妹的任何后代成为h4 ......有道理吗?
答案 0 :(得分:1)
此转化:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"*[starts-with(name(), 'H')
and
substring(name(),2) > 1
and
not(substring(name(),2) > 5)
]">
<xsl:element name="h{substring(name(),2)+1}">
<xsl:copy-of select="namespace::*"/>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
应用于以下XML文档(未提供源XML文档!):
<html>
<head/>
<H2> Some H2</H2>
<div>
<H3>Some H3</H3>
<div>
<H4>Some H4</H4>
<div>
<H5>Some H5</H5>
</div>
</div>
</div>
</html>
会产生想要的正确结果:
<html>
<head/>
<h3> Some H2</h3>
<div>
<h4>Some H3</h4>
<div>
<h5>Some H4</h5>
<div>
<h6>Some H5</h6>
</div>
</div>
</div>
</html>
<强>解释强>:
正确使用和覆盖 identity rule 。
正确使用模板和匹配模式。
正确使用标准XPath函数 starts-with()
和 substring()
。
正确使用 xsl:element
和 AVT s(属性值模板)。