使用xslt

时间:2018-07-05 09:22:47

标签: xml 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',则序列应为A节,C节。

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

sequence (序列)变量中,分组已经完成,但是它包含具有 attribute status ='remove'的元素。因此,在 modifiedseq 变量中,我需要删除具有 attribute status ='remove'的元素。 请任何人尝试帮助我。

1 个答案:

答案 0 :(得分:0)

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

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

位于http://xsltransform.hikmatu.com/gWcDMeu的XSLT 2示例。