Как выбрать предшествующие узлы текстового узла, начиная с определенного узла, а не корневого узла? - PullRequest
2 голосов
/ 06 мая 2010

Как выбрать предшествующие узлы текстового узла, начиная с определенного узла, чей идентификатор я знаю, вместо получения текстовых узлов из корневого узла?

Когда я вызываю следующий фрагмент из шаблона соответствия текстового узла, Я получаю все предыдущие текстовые узлы из корня. Я хочу изменить приведенный выше фрагмент кода, чтобы выбрать только те текстовые узлы, которые появляются после узла, имеющего определенный идентификатор, скажем, 123. То есть что-то вроде // * [@ id = '123']

          <xsl:template match="text()[. is $text-to-split]"> 
          <xsl:variable name="split-index" as="xsd:integer" 
           select="$index - sum(preceding::text()/string-length(.))"/> 
          <xsl:value-of select="substring(., 1, $split-index - 1)"/> 
          <xsl:copy-of select="$new"/> 
          <xsl:value-of select="substring(., $split-index)"/> 
          </xsl:template> 

         <xsl:variable name="text-to-split" as="text()?" 
         select="descendant::text()[sum((preceding::text(), .)/string-length(.)) ge $index][1]"/> 

Как включить условие в тех местах, где я использую предикат :: text, чтобы выбрать предшествующие текстовые узлы относительно идентификатора конкретного узла, который я знаю?

Ответы [ 2 ]

1 голос
/ 06 мая 2010

Вот несколько вариантов, которые вы можете использовать :

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:strip-space elements="*"/>
 <xsl:output method="text"/>

 <xsl:variable name="vStart" select="/*/*[@myId='123']/text()"/>
 <xsl:variable name="vEnd" select="/*/*[last()]"/>

    <xsl:template match="/">
      <xsl:value-of select=
       "*/*[last()]
             /sum(preceding::text()
                 intersect
                  $vStart/following::text()
                  )
     "/>
---------------
      <xsl:value-of select=
       "*/*[last()]
             /sum(preceding::text()[. >> $vStart])
     "/>
--------------- 
      <xsl:value-of select=
       "sum(/*/*[. >> $vStart and . &lt;&lt; $vEnd])
     "/>
    </xsl:template>
</xsl:stylesheet>

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

<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num myId='123'>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>010</num>
</nums>

получены желаемые результаты :

30
---------------
      30
--------------- 
      30
1 голос
/ 06 мая 2010

В XPath 2.0 вы можете использовать операторы << и >> для сравнения порядка узлов. Например:

preceding-sibling::text()[. >> $foo]

выделит все текстовые узлы, предшествующие текущему, которые следуют за узлом $foo в порядке документа. Конечно, вы можете использовать выражение вместо $foo - в вашем случае //*[@id='123'] - хотя связывание его с переменной и последующее использование его в фильтре может быть проще для процессора XSLT для оптимизации.

См. this для подробного описания этих операторов.

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