代码之家  ›  专栏  ›  技术社区  ›  Reegan

使用XSLT动态删除元素

  •  1
  • Reegan  · 技术社区  · 6 年前

    在HTML到XML的过程中,我需要删除一些具有特定属性的元素。这是通过动态在变量内部完成的。下面是输入和所需的输出。

    <body>
          <p class='h1'>the fisr A</p>
          <p class='txt'>one</p>
          <p>tow</p>
    
          <p class='h2' status='remove'></p>
          <p class='h3'>the sec sec B</p>
          <p class='txt'>the next text</p>
    
          <p class='h3'>the fisr C</p>
          <p class='txt'>four</p>
          <p class='txt'>five</p>
    
          <p class='h1' status="remove">the seccond A</p>
          <p class='txt'>the seccond txt</p>
    
          <p class='h2'>the second B</p>
          <p class='txt'>six</p>
          <p class='txt'>seven</p>
          <p class='h1' status="remove">the third A</p>
          <p class='txt'>eight</p>
          <p class='h2' status="remove">the third A</p>
          <p class='h3'>the third A</p>
          <p class='txt'>the third A</p>
       </body>
    

    按顺序将h1、h2、h3分组输出如下。即A、B、C部分。但一个主要的条件是,如果h1、h2或h3中存在属性status='remove',则应删除特定元素。例如,如果h2具有attribute status='remove',那么序列应该是sectionA,sectionC。

    <book>
       <sectionA>
          <title>the fisr A</title>
          <p xmlns="http://www.w3.org/1999/xhtml" class="txt">one</p>
          <p xmlns="http://www.w3.org/1999/xhtml">tow</p>
             <sectionC>
                <title>the sec sec B</title>
                <p xmlns="http://www.w3.org/1999/xhtml" class="txt">the next text</p>
             </sectionC>
             <sectionC>
                <title>the fisr C</title>
                <p xmlns="http://www.w3.org/1999/xhtml" class="txt">four</p>
                <p xmlns="http://www.w3.org/1999/xhtml" class="txt">five</p>
             </sectionC>
       </sectionA>
    
          <sectionB>
             <title>the second B</title>
             <p xmlns="http://www.w3.org/1999/xhtml" class="txt">six</p>
             <p xmlns="http://www.w3.org/1999/xhtml" class="txt">seven</p>
          </sectionB>
    
             <sectionC>
                <title>the third A</title>
                <p xmlns="http://www.w3.org/1999/xhtml" class="txt">the third A</p>
             </sectionC>
    </book>
    

    我完成的XSLT如下所示。

     <xsl:template match="body">
          <xsl:variable name="sequence">
          <book>
            <xsl:for-each-group select="p" group-starting-with="p[@class='h1']">
              <sectionA>
                <xsl:copy-of select="@*"></xsl:copy-of>
                <title>
                  <xsl:value-of select="node()"/>
                </title>
                <xsl:for-each-group select="current-group() except ." group-starting-with="p[@class='h2']">
                  <xsl:choose>
                    <xsl:when test="self::p[@class='h2']">
                      <sectionB>
                        <xsl:copy-of select="@*"></xsl:copy-of>
                        <title>
                          <xsl:value-of select="node()"/>
                        </title>
                        <xsl:for-each-group select="current-group() except ." group-starting-with="p[@class='h3']">
                          <xsl:choose>
                            <xsl:when test="self::p[@class='h3']">
                              <sectionC>
                                <xsl:copy-of select="@*"></xsl:copy-of>
                                <title>
                                  <xsl:value-of select="node()"/>
                                </title>
                                <xsl:apply-templates select="current-group() except ."></xsl:apply-templates>
                              </sectionC>
                            </xsl:when>
                            <xsl:otherwise>
                              <xsl:apply-templates select="current-group()"></xsl:apply-templates>
                            </xsl:otherwise>
                          </xsl:choose>
                        </xsl:for-each-group>
                      </sectionB>
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:apply-templates select="current-group()"></xsl:apply-templates>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:for-each-group>
              </sectionA>
            </xsl:for-each-group>
          </book>
          </xsl:variable>
          <xsl:variable name="modifiedseq">
                <xsl:apply-templates select="$sequence/node()"></xsl:apply-templates>
          </xsl:variable>
          <xsl:apply-templates select="$modifiedseq"></xsl:apply-templates>
        </xsl:template>
    
        <xsl:template match="p">
          <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="node()"/>
          </xsl:copy>
        </xsl:template>
    

    序列 变量分组已完成,但它包含 属性状态为“移除” .所以在 修改后的seq 变量我需要删除 属性状态为“移除” . 请任何人帮助我。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Martin Honnen    6 年前

    <xsl:template match="*[@status = 'remove']">
        <xsl:apply-templates/>
    </xsl:template>
    
    <xsl:template match="*[@status = 'remove']/title | *[@status = 'remove']/p"/>
    

    https://xsltfiddle.liberty-development.net/bdxtqc

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:math="http://www.w3.org/2005/xpath-functions/math"
        xmlns:map="http://www.w3.org/2005/xpath-functions/map"
        xmlns:array="http://www.w3.org/2005/xpath-functions/array"
        exclude-result-prefixes="xs math map array"
        version="3.0">
    
      <xsl:mode on-no-match="shallow-copy"/>
    
      <xsl:output indent="yes"/>
    
     <xsl:template match="body">
          <xsl:variable name="sequence">
          <book>
            <xsl:for-each-group select="p" group-starting-with="p[@class='h1']">
              <sectionA>
                <xsl:copy-of select="@*"></xsl:copy-of>
                <title>
                  <xsl:value-of select="node()"/>
                </title>
                <xsl:for-each-group select="current-group() except ." group-starting-with="p[@class='h2']">
                  <xsl:choose>
                    <xsl:when test="self::p[@class='h2']">
                      <sectionB>
                        <xsl:copy-of select="@*"></xsl:copy-of>
                        <title>
                          <xsl:value-of select="node()"/>
                        </title>
                        <xsl:for-each-group select="current-group() except ." group-starting-with="p[@class='h3']">
                          <xsl:choose>
                            <xsl:when test="self::p[@class='h3']">
                              <sectionC>
                                <xsl:copy-of select="@*"></xsl:copy-of>
                                <title>
                                  <xsl:value-of select="node()"/>
                                </title>
                                <xsl:apply-templates select="current-group() except ."></xsl:apply-templates>
                              </sectionC>
                            </xsl:when>
                            <xsl:otherwise>
                              <xsl:apply-templates select="current-group()"></xsl:apply-templates>
                            </xsl:otherwise>
                          </xsl:choose>
                        </xsl:for-each-group>
                      </sectionB>
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:apply-templates select="current-group()"></xsl:apply-templates>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:for-each-group>
              </sectionA>
            </xsl:for-each-group>
          </book>
          </xsl:variable>
          <xsl:variable name="modifiedseq">
                <xsl:apply-templates select="$sequence/node()"></xsl:apply-templates>
          </xsl:variable>
          <xsl:apply-templates select="$modifiedseq"></xsl:apply-templates>
        </xsl:template>
    
        <xsl:template match="p">
          <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="node()"/>
          </xsl:copy>
        </xsl:template>
    
        <xsl:template match="*[@status = 'remove']">
            <xsl:apply-templates/>
        </xsl:template>
    
        <xsl:template match="*[@status = 'remove']/title | *[@status = 'remove']/p"/>
    
    </xsl:stylesheet>
    

    xsl:mode

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

    http://xsltransform.hikmatu.com/gWcDMeu