Попробуйте получить счетчик составного паттерна в xsl - PullRequest
2 голосов
/ 31 марта 2012

Структура моей таблицы стилей следующая:

    <xsl:apply-templates select="pattern1|pattern2|pattern3"/>
        ...
    <xsl:template match="pattern1|pattern2|pattern3">
        <xsl:variable name="counter"> 
            <xsl:number/>
        </xsl:variable>
        ...
    </xsl:template>

Переменная counter сбрасывается для каждого шаблона.Я хочу получить счетчик для всех матчей.Как мне этого добиться?Спасибо!

Исходная структура XML выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <div class="entry">
        <div class="headword">
            ...
        </div>
        <div class="information-forms">
            test infomation block
        </div>
        <div class="definition">
            <div>text </div>
            <div>text </div>
                  ... ...
            <div>text </div>
        </div>
        <div class="example-sentences">
            <ol>
                <li>sentence here</li>
                <li>sentence here</li>
            ... ...
                <li>sentence here</li>
            </ol>
        </div>
        <div class="synonyms-reference">
            <div class="syn-para">
                Synonyms: ... ...
            </div>
            <div class="ant-para">
                Antonyms: ... ... 
            </div>
        <div class="...">
              ...
        </div>
        </div>
    </div>
    <div class="entry">
        ...
    </div>
    <div class="entry">
        ...
    </div>
    ... ... 
</root>

Я хочу получить счетчик узлов нескольких шаблонов под каждым узлом div [@ class = "entry"].

Таким образом, счетчик должен быть сброшен при запуске в новом узле div [@ class = "entry"].XPath шаблонов равен

div[@class='information-forms']
|
div[@class='definition'].div
|
div[@class='example-sentences']/ol/li

. Я могу понять, как это сделать, дважды проанализировав его с помощью таблицы стилей xsl. (Сначала поместите все совпадающие узлы в один узел.) Но мне кажется,можно сделать за один проход.Я надеюсь, что кто-то опытный в XSL / XSLT может мне помочь.Спасибо.

Ответы [ 3 ]

0 голосов
/ 01 апреля 2012

Попробуйте использовать

count(preceding::pattern1|preceding::pattern2|preceding::pattern3)

Чтобы снова запустить счетчик на каждом div[@class="entry"] узле, вы можете использовать

count(preceding::pattern1|preceding::pattern2|preceding::pattern3) - count(preceding::div[@class='entry'][1]/preceding::pattern1|preceding::div[@class='entry'][1]/preceding::pattern2|preceding::div[@class='entry'][1]/preceding::pattern3)‌​
0 голосов
/ 01 апреля 2012

Попробуйте следующее. Объяснение: вызовите определенный шаблон для набора обрабатываемых узлов, предоставив набор в качестве параметра, затем используйте position () в шаблоне.

<xsl:template match="div[@class='entry']">
    <div>
        <xsl:variable name="divs" select="
        div[@class='information-forms']
        |
        div[@class='definition']/div
        |
        div[@class='example-sentences']/ol/li
        "/>
        <xsl:call-template name="divs">
            <xsl:with-param name="divs" select="$divs"/>
        </xsl:call-template>
    </div>
</xsl:template>



<xsl:template name="divs">
    <xsl:param name="divs"/>
    <xsl:for-each select="$divs">
        <pos><xsl:value-of select="position()"/></pos>
    </xsl:for-each>
</xsl:template>

С введенным вами вводом XML это дает как результат

<?xml version="1.0" encoding="UTF-8"?>
<out>
    <div>
        <pos>1</pos>
        <pos>2</pos>
        <pos>3</pos>
        <pos>4</pos>
        <pos>5</pos>
        <pos>6</pos>
        <pos>7</pos>
    </div>
    <div/>
    <div/>
</out>
0 голосов
/ 31 марта 2012

Используйте соответственно count и level атрибуты xsl:number, как в приведенном ниже преобразовании :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match=
  "*[starts-with(name(), 'A') and contains(name(), '.')]
  |
   *[starts-with(name(), 'B') and contains(name(), '.')]
  |
   *[starts-with(name(), 'C') and contains(name(), '.')]
  ">
   <X oldname="{name()}">
    <xsl:number level="any" count=
  "*[starts-with(name(), 'A') and contains(name(), '.')]
  |
   *[starts-with(name(), 'B') and contains(name(), '.')]
  |
   *[starts-with(name(), 'C') and contains(name(), '.')]
  "/>
    <xsl:apply-templates/>
   </X>
  </xsl:template>
</xsl:stylesheet>

, когда это преобразование применяется к следующемуXML-документ :

<t>
    <A>
        <A.1>
            <A.1.1/>
            <A.1.2/>
        </A.1>
        <A.2>
            <A.2.1/>
        </A.2>
        <A.3/>
    </A>
    <B>
        <B.1/>
        <B.2>
            <B.2.1/>
            <B.2.2>
                <B.2.2.1/>
                <B.2.2.2/>
            </B.2.2>
        </B.2>
    </B>
    <C>
        <C.1/>
        <C.2>
            <C.2.1/>
            <C.2.2>
                <C.2.2.1/>
                <C.2.2.2/>
            </C.2.2>
        </C.2>
    </C>
</t>

желаемый правильный результат (абсолютная нумерация для всех элементов, чье имя содержит ".") получается :

<t>
    <A>
        <X oldname="A.1">1
            <X oldname="A.1.1">2</X>
            <X oldname="A.1.2">3</X></X>
        <X oldname="A.2">4
            <X oldname="A.2.1">5</X></X>
        <X oldname="A.3">6</X>
    </A>
    <B>
        <X oldname="B.1">7</X>
        <X oldname="B.2">8
            <X oldname="B.2.1">9</X>
            <X oldname="B.2.2">10
                <X oldname="B.2.2.1">11</X>
                <X oldname="B.2.2.2">12</X></X></X>
    </B>
    <C>
        <X oldname="C.1">13</X>
        <X oldname="C.2">14
            <X oldname="C.2.1">15</X>
            <X oldname="C.2.2">16
                <X oldname="C.2.2.1">17</X>
                <X oldname="C.2.2.2">18</X></X></X>
    </C>
</t>

Обновление : ОП не предоставил образец XML-документа и пояснил, что нумерация должна сбрасываться при каждом div[@class='entry].

Решение :

Это преобразование:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match=
  "div[@class='information-forms']
  |
   div[@class='definition']/div
  |
   div[@class='example-sentences']/ol/li
  ">
  <xsl:number level="any" 
  count="div[@class='information-forms']
              |
               div[@class='definition']/div
              |
               div[@class='example-sentences']/ol/li"
  from="div[@class='entry']"/>

  <xsl:call-template name="identity"/>
 </xsl:template>
</xsl:stylesheet>

при применении к следующему документу XML :

<root>
    <div class="entry">
        <div class="headword">
                ...
        </div>
        <div class="information-forms">
                test infomation block
        </div>
        <div class="definition">
            <div>text </div>
            <div>text </div>
                      ... ...
            <div>text </div></div>
        <div class="example-sentences">
            <ol>
                <li>sentence here</li>
                <li>sentence here</li>
                ... ...
                <li>sentence here</li>
            </ol>
        </div>
        <div class="synonyms-reference">
            <div class="syn-para">
                    Synonyms: ... ...
            </div>
            <div class="ant-para">
                    Antonyms: ... ...
            </div>
            <div class="...">
                  ...
            </div></div></div>
    <div class="entry">
            ...
    </div>
    <div class="entry">
        <div class="headword">
                ...
        </div>
        <div class="information-forms">
                test infomation block
        </div>
        <div class="definition">
            <div>text </div>
            <div>text </div>
                      ... ...
            <div>text </div></div>
        <div class="example-sentences">
            <ol>
                <li>sentence here</li>
                <li>sentence here</li>
                ... ...
                <li>sentence here</li>
            </ol>
        </div>
        <div class="synonyms-reference">
            <div class="syn-para">
                    Synonyms: ... ...
            </div>
            <div class="ant-para">
                    Antonyms: ... ...
            </div>
            <div class="...">
                  ...
            </div></div></div>
</root>

дает требуемый результат (требуемыйэлементы нумеруются, и номера сбрасываются в каждом div[@class='entry]):

<root>
   <div class="entry">
      <div class="headword">
                ...
        </div>1<div class="information-forms">
                test infomation block
        </div>
      <div class="definition">2<div>text </div>3<div>text </div>
                      ... ...
            4<div>text </div>
      </div>
      <div class="example-sentences">
         <ol>5<li>sentence here</li>6<li>sentence here</li>
                ... ...
                7<li>sentence here</li>
         </ol>
      </div>
      <div class="synonyms-reference">
         <div class="syn-para">
                    Synonyms: ... ...
            </div>
         <div class="ant-para">
                    Antonyms: ... ...
            </div>
         <div class="...">
                  ...
            </div>
      </div>
   </div>
   <div class="entry">
            ...
    </div>
   <div class="entry">
      <div class="headword">
                ...
        </div>1<div class="information-forms">
                test infomation block
        </div>
      <div class="definition">2<div>text </div>3<div>text </div>
                      ... ...
            4<div>text </div>
      </div>
      <div class="example-sentences">
         <ol>5<li>sentence here</li>6<li>sentence here</li>
                ... ...
                7<li>sentence here</li>
         </ol>
      </div>
      <div class="synonyms-reference">
         <div class="syn-para">
                    Synonyms: ... ...
            </div>
         <div class="ant-para">
                    Antonyms: ... ...
            </div>
         <div class="...">
                  ...
            </div>
      </div>
   </div>
</root>

Объяснение : правильное использование атрибута from xsl:number.

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