Как получить узлы на основе целого числа в строке, используя XSLT 2.0? - PullRequest
1 голос
/ 16 сентября 2011

Это мой XML-документ:

<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
    <w:body>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading1" />
            </w:ppr>
            <w:r>
                <w:t>Para1</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading2" />
            </w:ppr>
            <w:r>
                <w:t>Para2</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading3" />
            </w:ppr>
            <w:r>
                <w:t>Para3</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading4" />
            </w:ppr>
            <w:r>
                <w:t>Para4</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading1" />
            </w:ppr>
            <w:r>
                <w:t>Para5</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading3" />
            </w:ppr>
            <w:r>
                <w:t>Para6</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading4" />
            </w:ppr>
            <w:r>
                <w:t>Para7</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading2" />
            </w:ppr>
            <w:r>
                <w:t>Para8</w:t>
            </w:r>
        </w:p>
        <!-- This is my Current Node -->
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading3" />
            </w:ppr>
            <w:r>
                <w:t>Para9</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading1" />
            </w:ppr>
            <w:r>
                <w:t>Para10</w:t>
            </w:r>
        </w:p>
    </w:body>
</w:document>

Итак, читая каждый элемент, я хочу проверить атрибут w:val из w:ppr/w:pstyle. Например, в приведенном выше файле первый w:p содержит значение этого атрибута (w:ppr/w:pstyle/@w:val) как Heading1. Итак, для первого w:p мне все равно и просто беру это. После, взяли это w:p:

  1. Я хочу разделить значение атрибута Heading1 для получения строк после заголовка. Итак, теперь мы получаем 1. После этого при чтении следующего w:p примените ту же логику для разделения текущего значения атрибута. Итак, в этом случае мы имеем 2. Теперь я хочу сравнить текущее значение 2 с предыдущим значением 1.
  2. Если оно меньше предыдущего значения, выберите только текущее значение w:p. Иначе ничего не делай.

Примените вышеуказанные шаги 1 и 2 для всех узлов w:p. Итак, в моем случае я хочу выбрать только следующие w:p узлы.

Примеры выходных узлов (полное получение узла w: p):

<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
    <w:body>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading1" />
            </w:ppr>
            <w:r>
                <w:t>Para1</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading1" />
            </w:ppr>
            <w:r>
                <w:t>Para5</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading2" />
            </w:ppr>
            <w:r>
                <w:t>Para8</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading1" />
            </w:ppr>
            <w:r>
                <w:t>Para10</w:t>
            </w:r>
        </w:p>
    </w:body>
</w:document>

1 Ответ

2 голосов
/ 16 сентября 2011

Я полагаю, что вы хотите игнорировать узлы w: p , если соответствующий атрибут w: val больше w: val элемент предыдущего w: p (где он существует).

В терминах XPath, где ...

number(substring-after(w:ppr/w:pstyle/@w:val, 'Heading'))
>= number(substring-after(preceding-sibling::w:p[1]/w:ppr/w:pstyle/@w:val, 'Heading'))  

Вот полный XSLT, которыйявляется преобразованием идентичности, с дополнительным регистром, чтобы соответствовать таким w: p узлам и игнорировать их:

<xsl:stylesheet version="1.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
   xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="/">
      <xsl:apply-templates />
   </xsl:template>

   <xsl:template match="w:p
   [
      preceding-sibling::w:p[1] 
      and 
         number(substring-after(w:ppr/w:pstyle/@w:val, 'Heading')) 
         >= number(substring-after(preceding-sibling::w:p[1]/w:ppr/w:pstyle/@w:val, 'Heading'))   
   ]">
   </xsl:template>

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

   <xsl:template match="comment()" />
</xsl:stylesheet>

При применении к входной выборке генерируется следующий вывод:*

<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
   <w:body>
      <w:p>
         <w:ppr>
            <w:pstyle w:val="Heading1"/>
         </w:ppr>
         <w:r>
            <w:t>Para1</w:t>
         </w:r>
      </w:p>
      <w:p>
         <w:ppr>
            <w:pstyle w:val="Heading1"/>
         </w:ppr>
         <w:r>
            <w:t>Para5</w:t>
         </w:r>
      </w:p>
      <w:p>
         <w:ppr>
            <w:pstyle w:val="Heading2"/>
         </w:ppr>
         <w:r>
            <w:t>Para8</w:t>
         </w:r>
      </w:p>
      <w:p>
         <w:ppr>
            <w:pstyle w:val="Heading1"/>
         </w:ppr>
         <w:r>
            <w:t>Para10</w:t>
         </w:r>
      </w:p>
   </w:body>
</w:document>
...