-1

我正在尝试遍历我的 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# 标签的增量,如果我可以简单地让工作表输出完整的文档,并将所有 h# 标签转换为 h1 标签,我会感觉很好。任何人都可以帮忙吗?

谢谢。

编辑:

第一个答案是一个很大的帮助,但要清楚问题不仅仅是将所有 h# 标签增加一个,最多六个,它是找到所有 h# 标签,然后将它们设置为一个递增的数字,最多六个,取决于它们在文档层次结构中的深度。

这是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,然后任何兄弟姐妹的 hN 后代成为 h4.. . 有什么意义吗?

4

1 回答 1

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>

说明

  1. 正确使用和覆盖身份规则

  2. 正确使用模板和匹配模式。

  3. 正确使用标准 XPath 函数starts-with()substring().

  4. 正确使用xsl:elementAVT(属性值模板)。

于 2012-09-25T02:13:44.830 回答