Получить фактическую позицию элемента в XSLT - PullRequest
0 голосов
/ 17 февраля 2020

Я хочу получить фактическую позицию <p> с использованием XSLT.

Ввод:

<root> 
    <p>
        <pPr>
            <pStyle val="EQsolutionlist1"/>
        </pPr>
    </p>
   <p>
       <pPr>
           <pStyle val="AAA"/>
       </pPr>
   </p>
   <p>
       <pPr>
           <pStyle val="EQsolutionlist1"/>
       </pPr>
   </p>
</root>

Вывод должен быть:

<abc>
  <q>1</q>
  <q>2</q>
</abc>

Пробный код :

<xsl:template match="p/pPr[pStyle[@val = 'EQsolutionlist1']]">
   <abc>
     <q>
        <xsl:value-of select="ancestor::root//pPr[pStyle[val = 'EQsolutionlist1']]/position()"/>
     </q>
   </abc>
  </xsl:template>

Вывод, который я получаю:

<abc>
  <q>1 2</q>
  <q>1 2</q>
</abc>

Это означает, что на входе есть два p[pPr[pStyle[@val = 'EQsolutionlist1']]]. Я хочу напечатать позицию отдельно. В качестве моего кода все позиции печатаются на выходе. Как я могу решить эту проблему.

Я использую XSLT 2.0

Ответы [ 2 ]

0 голосов
/ 17 февраля 2020

Если вы используете xsl:number, вы можете сделать:

  <xsl:template match="p/pPr[pStyle[@val = 'EQsolutionlist1']]">
      <q>
          <xsl:number count="pPr[pStyle[@val = 'EQsolutionlist1']]" level="any"/>
      </q>
  </xsl:template>

Элемент результата abc должен быть создан выше при сопоставлении дерева ввода, так как вы хотите один, а не один для каждый pr:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>

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

  <xsl:template match="p/pPr[pStyle[@val = 'EQsolutionlist1']]">
      <q>
          <xsl:number count="pPr[pStyle[@val = 'EQsolutionlist1']]" level="any"/>
      </q>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/6rexjif

0 голосов
/ 17 февраля 2020

В качестве первого шага рассмотрим следующие действия:

  <xsl:template match="p/pPr[pStyle[@val = 'EQsolutionlist1']]">
   <abc>
     <q>
        <xsl:value-of select="position()"/>
     </q>
   </abc>
  </xsl:template>

Однако это не совсем правильно, поскольку position() здесь дает вам положение узла в наборе узлов, выбранных xsl: apply-templates, а не положение узла в наборе узлов, совпадающих с этим конкретным правилом шаблона.

Так что вам нужно изменить xsl: apply-templates, который запускает это правило шаблона, так что он выбирает только узлы, которые вы хотите пронумеровать: переместите предикат [pStyle[@val = 'EQsolutionlist1']] в инструкцию xsl:apply-templates.

Помните, что position() дает вам положение элемента контекста в последовательности элементов, которые вы в данный момент обрабатываете.

Если вы используете position() в правой части «/», как в A/position(), «/» означает, что выражение справа будет оцениваться один раз для каждого элемента, выбранного выражением в оставил; «последовательность элементов, которые вы сейчас обрабатываете» - это набор узлов, выбранных A, и их позиции равны 1, 2, 3, ... N, где N - количество узлов, выбранных выражением A. Что не вы хотите вообще.

Если вы используете position() в самом внешнем коде правила шаблона, «последовательность элементов, которые вы сейчас обрабатываете» - это последовательность, выбранная инструкцией xsl:apply-templates, которая инициировала выполнение это шаблонное правило.

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