XSLT如果parent = a且child = b则将b中的兄弟b移动到b中

时间:2016-06-16 14:07:48

标签: xslt

我有大量具有以下结构的html文件:

<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <title>t</title>
  </head>
  <body>
    <div class="a">
      <div class="i">i</div>
      <div class="b">b1
        <div class="b1">b11</div>
        <div class="b2">b12</div>
      </div>
      <div class="j">j</div>
      <div class="b">b2
        <div class="b1">b21</div>
        <div class="b2">b22</div>
      </div>
      <div class="k">k</div>
    </div>
    <div class="x">
      <div class="i">i3</div>
      <div class="b">b3
        <div class="b1">b31</div>
        <div class="b2">b32</div>
      </div>
      <div class="j">j3</div>
    </div>
  </body>
</html>

我想:

  1. 移动b里面的所有兄弟姐妹
  2. 删除父a但保留其内容
  3. 请注意:

    1. div class =“a”没有text()
    2. div class =“b”可以有除div class =“a”之外的其他父项,例如div class =“x”
    3. div class =“a”可以包含1:N div class =“b”
    4. 输出应如下所示:

      <html>
        <head>
          <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
          <title>t</title>
        </head>
        <body>
          <div class="b">b1
            <div class="b1">b11</div>
            <div class="b2">b12</div>
            <div class="i">i</div>
            <div class="j">j</div>
            <div class="k">k</div>
          </div>
          <div class="b">b2
            <div class="b1">b21</div>
            <div class="b2">b22</div>
            <div class="i">i</div>
            <div class="j">j</div>
            <div class="k">k</div>
          </div>
          <div class="x">
            <div class="i">i3</div>
            <div class="b">b3
              <div class="b1">b31</div>
              <div class="b2">b32</div>
            </div>
            <div class="j">j3</div>
          </div>
        </body>
      </html>
      

      我正在使用类似于以下内容的shell脚本:

      xsltproc a.xslt a.html > b.html
      

      其中a.xslt如下:

      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
       <xsl:output omit-xml-declaration="yes" indent="yes"/>
       <xsl:strip-space elements="*"/>
      
       <xsl:template match="node()|@*" name="identity">
        <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
       </xsl:template>
      
       <xsl:template match="div[@class='a']/div[@class='b']">
          <xsl:apply-templates select="@*|preceding-sibling()[not(self::div[@class='b'])]"/>
          <xsl:apply-templates select="@*|following-sibling()[not(self::div[@class='b'])]"/>
          <xsl:copy-of select="div[@class='b']"/>
       </xsl:template>
      
      </xsl:stylesheet>
      

      但是我收到错误,可能是因为我没有正确使用previous-sibling和follow-sibling:

      xmlXPathCompOpEval: function preceding-sibling not found
      

      你能告诉我如何解开这个xslt吗?

1 个答案:

答案 0 :(得分:1)

我相信这符合您的指示:

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>

<!-- remove parent a but keep its content -->
<xsl:template match="div[@class='a']">
    <xsl:apply-templates/>
</xsl:template>

<!-- move all siblings of b inside b -->
<xsl:template match="div[@class='b']">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
        <xsl:copy-of select="../node()[not(self::div[@class='b'])]"/>
    </xsl:copy>
</xsl:template>

<!-- do not process siblings of b -->
<xsl:template match="node()[../div[@class='b']][not(self::div[@class='b'])]"/>

</xsl:stylesheet>

但是,结果不是你所展示的:

<html>
   <head>
      <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
      <title>t</title>
   </head>
   <body>
      <div class="b">b1
        <div class="b1">b11</div>
         <div class="b2">b12</div>
         <div class="i">i</div>
         <div class="j">j</div>
         <div class="k">k</div>
      </div>
      <div class="b">b2
        <div class="b1">b21</div>
         <div class="b2">b22</div>
         <div class="i">i</div>
         <div class="j">j</div>
         <div class="k">k</div>
      </div>
      <div class="x">
         <div class="b">b3
        <div class="b1">b31</div>
            <div class="b2">b32</div>
            <div class="i">i3</div>
            <div class="j">j3</div>
         </div>
      </div>
   </body>
</html>