1

在 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'的元素。因此,在modifiedseq变量中,我需要删除具有属性 status='remove'的元素。请任何人尝试帮助我。

4

1 回答 1

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>

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

于 2018-07-05T09:59:00.817 回答