Удалить элементы динамически, используя xslt - PullRequest
0 голосов
/ 05 июля 2018

В процессе html to 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 в последовательном порядке. Это раздел А, раздел В, раздел С. Но одним из основных условий является наличие атрибута status = 'remove' в h1, h2 или h3, тогда определенный элемент должен быть удален. например, если 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>

В переменной sequence группирование выполнено, но оно содержит элементы, имеющие атрибут status = 'remove' . Поэтому в переменной ifiedseq мне нужно удалить элементы, имеющие атрибут status = 'remove' . ПОЖАЛУЙСТА, кто-нибудь попытаться помочь мне.

1 Ответ

0 голосов
/ 05 июля 2018

Поскольку вы уже выполняете постобработку сгруппированных элементов, вы можете просто добавить два шаблона

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...