2014-10-06 2 views
1

Я нахожу способ использовать функции xpath previous/before-sibling, чтобы подсчитать количество тегов над итерацией в нескольких xml-файлах.Xpath query over xslt <collection> переменная

Я использую функцию «коллекции», чтобы «объединить» несколько XML, как показано ниже:

  <?xml version='1.0'?> 
     <xsl:stylesheet version='2.0' xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
      <xsl:output indent="yes"/> 
      <xsl:variable name="input" select="collection('./docs.xml')"/> 

      <xsl:template name="genTOC"> 
      ... 

       <xsl:for-each select="$input/library"> 
        <xsl:value-of select="count (preceding::library) +1" /> 
      ... 

Где docs.xml содержит ссылки на ряд XML-файла структурированного, как показано ниже:

<library> 
    <book> 
     <title>The Art of Computer Programming</title> 
     <price>198</price> 
     <author>Donald Knuth</author> 
     <ISBN>0201485419</ISBN> 
    </book> 
    <book> 
     <title>The C Programming Language</title> 
     <price>46.96</price> 
     <author>Brian Wilson Kernighan</author> 
     <ISBN>0131103628</ISBN> 
    </book> 
</library> 

Но кажется, что я не могу считать предыдущее, как в другом XML-файле. Я пробовал также с

count (../preceding::library) 

ответ

1

Я думаю, что вы просто хотите

  <xsl:for-each select="$input/library"> 
       <xsl:value-of select="position()" /> 

Если вы действительно думаете, что нужно для навигации по коллекции, то вы можете создать временное дерево (фрагмент) в переменных

<xsl:variable name="my-library"> 
    <xsl:copy-of select="$input/library"/> 
</xsl:variable> 

<xsl:for-each select="$my-library/library"> 
    <xsl:value-of select="1 + preceding-sibling::library"/> 
</xsl:for-each> 

но, конечно, вы потребляете гораздо больше памяти, чем это делается по сравнению с простой обработкой входной коллекции.

+0

Это, конечно, решит конкретную проблему, спасибо! Но, вообще говоря, непонятно, почему мой способ не работал – profires

+0

Если вы используете 'collection' для загрузки коллекции документов, то в итоге вы получаете последовательность узлов документа, в то время как ориентация дерева деревьев и топографий XPath определяется на одном дереве, там нет осей для навигации по различным деревьям. –

+0

+1 хороший ответ, как обычно. Мартин, вы можете помочь мне понять более общий принцип - например, из spec - почему 'previous ::' не перекрещивает документы, а 'position()' делает? Например. спецификация в http://www.w3.org/TR/xpath20/#axes говорит, что «предыдущая ось содержит все узлы, которые являются потомками корня дерева, в котором найден контекстный узел», но я не конечно, как мы знаем, что «корень дерева» означает корень документа, и коллекция не может считаться деревом с собственным корнем. – LarsH