如何在XSLT1.0中匹配和包装相同和相邻的节点

  • 本文关键字:包装 节点 XSLT1 xslt xslt-1.0
  • 更新时间 :
  • 英文 :


我有一个XML文件,看起来像这样,我正试图用div包装彼此相邻的"Para_bb"节点。

   <Para_a></Para_a>
   <Para_a></Para_a>
   <Para_bb></Para_bb>
   <Para_bb></Para_bb>
   <Para_bb></Para_bb>
   <Para_bb></Para_bb>
   <Para_a></Para_a>
   <Para_bb></Para_bb>
   <Para_bb></Para_bb>
   <Para_a></Para_a>
   <Para_a></Para_a>
   <Para_bb></Para_bb>

我怎么能把它做成这样?

   <p></p>
   <p></p>
   <div class="blackBox">
      <Para_bb></Para_bb>
      <Para_bb></Para_bb>
      <Para_bb></Para_bb>
      <Para_bb></Para_bb>
   </div>
   <p></p>
   <div class="blackBox">
      <Para_bb></Para_bb>
      <Para_bb></Para_bb>
   </div>
   <p></p>
   <p></p>
   <div class="blackBox">
      <Para_bb></Para_bb>
   </div>

您可以定义如下键:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:key name="group" match="Para_bb[preceding-sibling::*[1][self::Para_bb]]" use="generate-id(preceding-sibling::Para_bb[not(preceding-sibling::*[1][self::Para_bb])][1])"/>
<xsl:template match="Root">
  <body>
    <xsl:apply-templates/>
  </body>
</xsl:template>
<xsl:template match="Para_a">
  <p>
    <xsl:apply-templates/>
  </p>
</xsl:template>
<xsl:template match="Para_bb[preceding-sibling::*[1][self::Para_bb]]"/>
<xsl:template match="Para_bb[not(preceding-sibling::*[1][self::Para_bb])]">
  <div class="blackBox">
    <xsl:copy-of select=". | key('group', generate-id())"/>
  </div>
</xsl:template>
</xsl:stylesheet>

这改变了

<Root>
   <Para_a></Para_a>
   <Para_a></Para_a>
   <Para_bb>1</Para_bb>
   <Para_bb>2</Para_bb>
   <Para_bb>3</Para_bb>
   <Para_bb>4</Para_bb>
   <Para_a></Para_a>
   <Para_bb>5</Para_bb>
   <Para_bb>6</Para_bb>
   <Para_a></Para_a>
   <Para_a></Para_a>
   <Para_bb>7</Para_bb>
</Root>

进入

<body>
   <p/>
   <p/>
   <div class="blackBox">
      <Para_bb>1</Para_bb>
      <Para_bb>2</Para_bb>
      <Para_bb>3</Para_bb>
      <Para_bb>4</Para_bb>
   </div>


   <p/>
   <div class="blackBox">
      <Para_bb>5</Para_bb>
      <Para_bb>6</Para_bb>
   </div>

   <p/>
   <p/>
   <div class="blackBox">
      <Para_bb>7</Para_bb>
   </div>
</body>

XSLT1.0中实现这一点的一种方法是使用一个模板来匹配组中每个Para_bb元素的第一个出现

<xsl:template match="Para_bb[not(preceding-sibling::*[1][self::Para_bb])]">

然后,您将调用一个新模板,并指定一个模式,就在第一个元素上

    <p>
        <xsl:apply-templates select="." mode="div" />
    </p>

然后,在与指定模式匹配的模板中,复制元素并选择下一个同级元素,但前提是它是另一个Para_bb

<xsl:template match="Para_bb" mode="div">
    <xsl:call-template name="identity" />
    <xsl:apply-templates select="following-sibling::*[1][self::Para_bb]" mode="div"/>
</xsl:template>

(其中被调用的命名模板是标准身份模板)

尝试此XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="Para_bb[not(preceding-sibling::*[1][self::Para_bb])]">
        <div class="blackBox">
            <xsl:apply-templates select="." mode="div" />
        </div>
    </xsl:template>
    <xsl:template match="Para_bb" />
    <xsl:template match="Para_a">
        <p>
            <xsl:apply-templates select="@*|node()"/>
        </p>
    </xsl:template>
    <xsl:template match="Para_bb" mode="div">
        <xsl:call-template name="identity" />
        <xsl:apply-templates select="following-sibling::*[1][self::Para_bb]" mode="div"/>
    </xsl:template>
    <xsl:template match="@*|node()" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

相关内容

  • 没有找到相关文章

最新更新