XSLT删除父级并保留子级,重命名祖父级,并按给定顺序对子级进行排序

时间:2016-06-15 15:47:42

标签: xslt

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

<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <title>t</title>
  </head>
  <body>
    <div class="z">
      <div class="m">m1</div>
      <div class="y">
        <div class="a">a1</div>
        <div class="b">b1</div>
        <div class="x">
          <div class="a">a2</div>
        </div>
        <div class="c">c1</div>
      </div>
      <div class="n">n1</div>
    </div>
    <div class="y">
      <div class="c">c2</div>
      <div class="d">d1</div>
      <div class="x">
        <div class="a">a3</div>
      </div>
      <div class="b">b2</div>
    </div>
  </body>
</html>

我想:

  1. 删除所有div class =&#34; x&#34;但要保持其内容; div class =&#34; x&#34;没有文字节点
  2. 重命名所有div class =&#34; y&#34;到div class =&#34; x&#34 ;; div class =&#34; y&#34;没有文字节点
  3. 订购div class =&#34; x&#34;中的节点按特定顺序(不一定按字母顺序排列):a,b,c,任何其他。
  4. 如果有多个div类=&#34; a&#34;他们的订单没有偏好; div class =&#34; b&#34;,div class =&#34; c&#34 ;, any other。
  5. 最终输出应如下所示:

    <html>
      <head>
        <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
        <title>t</title>
      </head>
      <body>
        <div class="z">
          <div class="m">m1</div>
          <div class="x">
            <div class="a">a1
            <div class="a">a2
            <div class="b">b1
            <div class="c">c1
          </div>
          <div class="n">n1</div>
        </div>
        <div class="x">
          <div class="a">a3
          <div class="b">b2
          <div class="c">c2
          <div class="d">d1
        </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='x']" >
      <xsl:apply-templates select="*|text()" />
     </xsl:template>
    
     <xsl:template match="div[@class='y']" >
      <div class="x">
       <xsl:apply-templates select="*|text()" />
      </div>
     </xsl:template>
    
    </xsl:stylesheet>
    

    我的输出几乎存在,但节点不按顺序排列:a,b,c,任何其他节点。

    <html>
      <head>
        <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
        <title>t</title>
      </head>
      <body>
        <div class="z">
          <div class="m">m1</div>
          <div class="x">
            <div class="a">a1</div>
            <div class="b">b1</div>
            <div class="a">a2</div>
            <div class="c">c1</div>
          </div>
          <div class="n">n1</div>
        </div>
        <div class="x">
          <div class="c">c2</div>
          <div class="d">d1</div>
          <div class="a">a3</div>
          <div class="b">b2</div>
        </div>
      </body>
    </html>
    

    您对如何按正确顺序对它们进行排序有什么建议吗?

    步骤1和2是获得此类输出的正确方法,还是应该使用不同的方法?

1 个答案:

答案 0 :(得分:1)

我不确定这是否完全符合您的需求,但请尝试使用此备用模板进行匹配div[@class='y']

<xsl:template match="div[@class='y']" >
  <div class="x">
   <xsl:apply-templates select="*[not(self::div[@class='x'])]|div[@class='x']/*">
     <xsl:sort select="@class" />  
   </xsl:apply-templates>
  </div>
 </xsl:template>

这将选择不是@class="x"的div的所有子节点,以及@class="x"

的任何div的直接子节点

在这种情况下,您可以删除与div[@class='x']匹配的模板。