Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
位置分组:html的xslt转换_Xslt_Xslt 2.0 - Fatal编程技术网

位置分组:html的xslt转换

位置分组:html的xslt转换,xslt,xslt-2.0,Xslt,Xslt 2.0,我有下面的html文件,我想运行一个转换,这样所有的h1、h2、h3标记都将转换成相应的div。h2将始终是h1的嵌套div,如果有2个h2标记,那么它应该有自己的div。同样,h3将始终是h2的嵌套div <body> <p> this is a text</p> <a href="http://yahoo.com">click here</a> <h3>this is heading 3</h3&

我有下面的html文件,我想运行一个转换,这样所有的h1、h2、h3标记都将转换成相应的div。h2将始终是h1的嵌套div,如果有2个h2标记,那么它应该有自己的div。同样,h3将始终是h2的嵌套div

<body>
   <p> this is a text</p>
   <a href="http://yahoo.com">click here</a>
   <h3>this is heading 3</h3>
   <p>text for heading 3</p>
    <h1>
      heading 1
   </h1>
     this is a text for heading 1
     <a href="link"> This is a link </a>
  <h2>
       this is heading 2

  </h2>
          this is a text for heading 2
  <h2>
          this is heading 2 again
  </h2>
         this is a text for heading 2 again
  </body>

这是一篇课文

这是标题3 标题3的案文

标题1 这是标题1的文本 这是标题2 这是标题2的文本 这又是标题2 这是标题2的文本
" 上面的输出应如下所示:

<body>
   <p> this is a text</p>
   <a href="http://yahoo.com">click here</a>
   <div>
    <heading>this is heading 3</heading>
   <p>text for heading 3</p>
    <div>

 <div>
  <heading>
    heading 1
  </heading>
  this is a text for heading 1
  <a href="link"> This is a link </a>
  <div>
    <heading>
           this is heading 2
      </heading>
     this is a text for heading 2
 </div>
 <div>
    <heading>
          this is heading 2 again
    </heading>
          this is a text for heading 2 again
  </div>
</div>
</body>

这是一篇课文

这是标题3 标题3的案文

标题1 这是标题1的文本 这是标题2 这是标题2的文本 这又是标题2 这是标题2的文本

任何帮助都将不胜感激。目前我已经在asp.net中完成了这项工作,但希望将其转换为xslt。

以下是xslt 2.0样式表:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:mf="http://example.com/mf"
  exclude-result-prefixes="xs mf"
  version="2.0">

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>

  <xsl:function name="mf:group" as="node()*">
    <xsl:param name="nodes" as="node()*"/>
    <xsl:param name="level" as="xs:integer"/>
    <xsl:param name="max-level" as="xs:integer"/>
    <xsl:choose>
      <xsl:when test="$level le $max-level">
        <xsl:for-each-group select="$nodes" group-starting-with="*[local-name() eq concat('h', $level)]">
          <xsl:choose>
            <xsl:when test="self::*[local-name() eq concat('h', $level)]">
              <div>
                <xsl:apply-templates select="."/>
                <xsl:sequence select="mf:group(current-group() except ., $level + 1, $max-level)"/>
              </div>
            </xsl:when>
            <xsl:otherwise>
              <xsl:apply-templates select="current-group()"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:for-each-group>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="$nodes"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:function>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@*, node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*[h1]">
    <xsl:copy>
      <xsl:sequence select="mf:group(node(), 1, 3)"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="h1 | h2 | h3">
    <heading>
      <xsl:apply-templates/>
    </heading>
  </xsl:template>

</xsl:stylesheet>

将Saxon 9.3应用于输入时

<body>
 <h1>
    heading 1
 </h1>
     this is a text for heading 1
     <a href="link"> This is a link </a>
  <h2>
       this is heading 2

  </h2>
          this is a text for heading 2
  <h2>
          this is heading 2 again
  </h2>
         this is a text for heading 2 again
</body>

标题1
这是标题1的文本
这是标题2
这是标题2的文本
这又是标题2
这是标题2的文本
我得到以下输出

<body>
   <div>
      <heading>
    heading 1
 </heading>
     this is a text for heading 1
     <a href="link"> This is a link </a>
      <div>
         <heading>
       this is heading 2

  </heading>
          this is a text for heading 2
  </div>
      <div>
         <heading>
          this is heading 2 again
  </heading>
         this is a text for heading 2 again
</div>
   </div>
</body>

标题1
这是标题1的文本
这是标题2
这是标题2的文本
这又是标题2
这是标题2的文本

我没有使用任何其他更复杂的输入测试XSLT,因此请测试您自己,如果遇到任何问题,请报告。

以下是XSLT 2.0样式表:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:mf="http://example.com/mf"
  exclude-result-prefixes="xs mf"
  version="2.0">

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>

  <xsl:function name="mf:group" as="node()*">
    <xsl:param name="nodes" as="node()*"/>
    <xsl:param name="level" as="xs:integer"/>
    <xsl:param name="max-level" as="xs:integer"/>
    <xsl:choose>
      <xsl:when test="$level le $max-level">
        <xsl:for-each-group select="$nodes" group-starting-with="*[local-name() eq concat('h', $level)]">
          <xsl:choose>
            <xsl:when test="self::*[local-name() eq concat('h', $level)]">
              <div>
                <xsl:apply-templates select="."/>
                <xsl:sequence select="mf:group(current-group() except ., $level + 1, $max-level)"/>
              </div>
            </xsl:when>
            <xsl:otherwise>
              <xsl:apply-templates select="current-group()"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:for-each-group>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="$nodes"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:function>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@*, node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*[h1]">
    <xsl:copy>
      <xsl:sequence select="mf:group(node(), 1, 3)"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="h1 | h2 | h3">
    <heading>
      <xsl:apply-templates/>
    </heading>
  </xsl:template>

</xsl:stylesheet>

将Saxon 9.3应用于输入时

<body>
 <h1>
    heading 1
 </h1>
     this is a text for heading 1
     <a href="link"> This is a link </a>
  <h2>
       this is heading 2

  </h2>
          this is a text for heading 2
  <h2>
          this is heading 2 again
  </h2>
         this is a text for heading 2 again
</body>

标题1
这是标题1的文本
这是标题2
这是标题2的文本
这又是标题2
这是标题2的文本
我得到以下输出

<body>
   <div>
      <heading>
    heading 1
 </heading>
     this is a text for heading 1
     <a href="link"> This is a link </a>
      <div>
         <heading>
       this is heading 2

  </heading>
          this is a text for heading 2
  </div>
      <div>
         <heading>
          this is heading 2 again
  </heading>
         this is a text for heading 2 again
</div>
   </div>
</body>

标题1
这是标题1的文本
这是标题2
这是标题2的文本
这又是标题2
这是标题2的文本

我没有使用任何其他更复杂的输入测试XSLT,所以请测试您自己,如果遇到任何问题,请报告。

我认为您的源标记中需要一个根元素,因此如果您的HTML与您发布的内容完全相同,则无法工作。嗨,DanMan,我添加了根元素体。好问题,+1。请参阅我的完整XSLT 1答案.0解决方案,非常简单,非常简短(比提供的XSLT 2.0解决方案短得多)而且高效——使用键。我认为您的源标记中需要一个根元素,因此如果您的HTML与您发布的内容完全相同,它将无法工作。嗨,DanMan,我添加了根元素主体。好问题,+1。请参阅我的答案,以获得一个完整的XSLT 1.0解决方案,该解决方案非常简单,非常简短(比提供的XSLT 2.0解决方案短得多)而且高效——使用钥匙。