Как выбрать все текстовые узлы между двумя элементами, используя XSL? - PullRequest
3 голосов
/ 23 апреля 2010

Я хочу получить generate-id(.) всех текстовых узлов после узла <m/> и перед узлом </n>. Я ищу какой-то общий XSL и не тесно связанный с образцом ввода, упомянутым ниже. Для любого шаблона ввода я хочу получить идентификаторы всех текстовых узлов между узлами <m/> и <n/>.

Пример ввода для лучшего понимания:

<a>
  <b> 
    <c>
      This is first text node
    </c> 
  </b> 
  <d> 
    <e>
      This is my second text node
    </e> 
    <f> 
      This is my <m/>third text node 
    </f> 
    <g>
      One more text node
    </g>
  <h>
    <i>
      This is my fourth text node
    </i>
  </h>
  <j> 
    This is my fifth <n/>text node 
  </j>
  <k> 
    <l>
      This is my sixth text node 
    </l>
  </k>     
</d> 
</a> 

Ожидаемый результат: Генерация идентификатора текстовых узлов со значениями «третий текстовый узел», «Еще один текстовый узел», «Это мой четвертый текстовый узел», «Это мой пятый», которые находятся между узлами <m/> и <n/>

Пожалуйста, дайте ваши идеи.

1 Ответ

4 голосов
/ 23 апреля 2010

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

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

 <xsl:variable name="vtextPostM" select="//text()[preceding::m]"/>
 <xsl:variable name="vtextPreN" select="//text()[following::n]"/>

 <xsl:variable name="vtextBN-MandN" select=
  "$vtextPostM[count(.|$vtextPreN) = count($vtextPreN)]"/>

 <xsl:variable name="vNL" select="'&#xA;'"/>
 <xsl:variable name="vQ">"</xsl:variable>

 <xsl:template match="/">
   <xsl:for-each select="$vtextBN-MandN">
    <xsl:value-of select=
     "concat($vNL, 'Id: ', $vQ, generate-id(), $vQ,
            'Text: ', $vQ, ., $vQ)
     "/>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному XML-документу дает правильный и требуемый результат :

Id: "IDAOZDLB"Text: "third text node
    "
Id: "IDAQZDLBIDAQZDLB"Text: "
      One more text node
    "
Id: "IDAUZDLBIDAUZDLB"Text: "
      This is my fourth text node
    "
Id: "IDAYZDLB"Text: "
    This is my fifth "

Обратите внимание на использование метода Кайса пересечения наборов узлов:

$ns1[count(.|$ns2)=count($ns2)]

выбирает все узлы, которые принадлежат как к набору узлов $ns1, так и к набору узлов $ns2.

...