使用xslt动态删除元素

里根

在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的状态为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>

序列变量中,分组已完成,但它包含具有status == remove属性的元素因此,在Modifyseq变量中,我需要删除属性为status ='remove'的元素请任何人尝试帮助我。

马丁·洪恩

由于已经对分组的元素进行了后期处理,因此您只需添加两个模板即可

<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>

是XSLT 3,如果您使用XSLT 2处理器,请xsl:mode用身份转换模板替换

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

有关XSLT 2示例,请访问http://xsltransform.hikmatu.com/gWcDMeu

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章