如何在 HTML 中将一系列具有相同类的兄弟元素分组?

问题描述 投票:0回答:1

我想使用 XSLT 1.0 处理以下输入 HTML,以便对一系列同级元素进行分组。

<html>
  <head>
    <meta charset="utf-8" />
  </head>
  <body>
    <div>
      <p>A</p>
      <div class="case1">0</div>
      <div class="case1">1</div>
      <div class="case1">2</div>
      <p>B</p>
      <p>C</p>
      <div class="case2">3</div>
      <div class="case2">4</div>
      <p>D</p>
      <p>E</p>
      <div class="case1">5</div>
      <div class="case1">6</div>
    </div>
  </body>
</html>

预期输出如下

<?xml version="1.0"?>
<html>
  <head>
    <meta charset="utf-8"/>
  </head>
  <body>
    <div>
      <p>A</p>
      <box class="case1">
        <p>0</p>
        <p>1</p>
        <p>2</p>
      </box>
      <p>B</p>
      <p>C</p>
      <box class="case2">
        <p>3</p>
        <p>4</p>
      </box>
      <p>D</p>
      <p>E</p>
      <box class="case1">
        <p>5</p>
        <p>6</p>
      </box>
    </div>
  </body>
</html>

我尝试写了下面的XSL,但是

mode="inbox"
没有生效,只有最后一个
<xsl:template match="div[contains(@class, 'case')]" />
生效,导致盒子里的内容变空了

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

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

  <!-- For the case of "case1". -->
  <xsl:template match="div[@class='case1'][not(preceding-sibling::*[1][@class='case1'])]">
    <box>
      <xsl:apply-templates select="." mode="inbox" />
      <xsl:apply-templates select="following-sibling::div[@class='case1'][preceding-sibling::*[not(self::div[@class='case1'])][1]/following-sibling::div[@class='case1'][1] = current()]" mode="inbox" />
    </box>
  </xsl:template>
  <xsl:template match="div[@class='case1']" mode="inbox">
    <p><xsl:apply-templates select="node()" /></p>
  </xsl:template>
  <xsl:template match="div[@class='case1']" />
</xsl:stylesheet>
<!-- For case2, similarly -->

如果您不介意,我将不胜感激任何建议。

xml xslt-1.0
1个回答
0
投票

我想你想做的事:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" 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="div[@class]">
    <xsl:if test="not(@class=preceding-sibling::div[1]/@class)">
        <box class="{@class}">
            <xsl:apply-templates select="." mode="inbox" />
        </box>
    </xsl:if>
</xsl:template>

<xsl:template match="div" mode="inbox">
    <p>
        <xsl:apply-templates/>
    </p>
    <xsl:apply-templates select="following-sibling::div[1][@class=current()/@class]" mode="inbox" />
</xsl:template>
    
</xsl:stylesheet>
© www.soinside.com 2019 - 2024. All rights reserved.