Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > XML, XSL > Сквозная нумерация элементов


Автор: Royan 6.6.2006, 20:14
Есть документ
Код

<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type='text/xsl' href='test.xslt'?>
<root>
    <parent>
        <child>AAAA</child>
        <child>BBBB</child>
        <child>CCCC</child>
        <child>DDDD</child>
    </parent>
    <parent>
        <child>EEEE</child>
        <child>FFFF</child>
        <child>GGGG</child>
    </parent>
    <parent>
        <child>HHHH</child>
        <child>IIII</child>
    </parent>    
</root>


Мне необходимо пронумеровать child ноды сквозной нумерацией, чтобы получилось в точности как здесь: http://forum.vingrad.ru/index.php?showtopic=89834&view=findpost&p=689196
а именно

1) АААА
2) BBBB
3) CCCC
4) DDDD
5) EEEE
6) FFFF
7) GGGG
8) HHHH
9) IIII


Но моя проблема отличается тем, что я уже сделал выборку по parent и мне очень важно ее сохранить. То есть я хочу нумеровать child из выборки по /root/parent. Единственным решением в лоб, которое я вижу это внутри моего <for-eacn select="/root/parent"> делать еще один <for-eacn select="//child"> в котором child будут сравниваться по generate-id() и уже оттуда получать текущий номер child'а, но это представляется мне очень не эффективным.

Вот пример того, что придумалось мне, возможно ли сделать эффективнее?
Код


<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" encoding="UTF-8" />
    <xsl:template match="/">
        <xsl:for-each select="/root/parent">
            <xsl:for-each select="child">
                <xsl:variable name="curChild" select="."/>
                <xsl:variable name="desiredPosition"/>
                <xsl:for-each select="//child">
                    <xsl:if test="generate-id($curChild)=generate-id()">
                        <xsl:variable name="desiredPosition" select="position()"/>
                        <xsl:value-of select="position()"/>
                    </xsl:if>
                </xsl:for-each>
            <xsl:value-of select="concat($desiredPosition, ') ', ., '&#xA;')"/>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
 

Автор: Beard 8.6.2006, 19:37
Этот пример не может работать - дважды встречается переменная desiredPosition (опечатка,
видимо), и 
Код

<xsl:if test="generate-id($curChild)=generate-id()">

  можно заменить на
Код

<xsl:if test=".=$curChild">


Сходу я бы сделал так (не факт, что лучший способ, но работать побыстрее должно, чем в Вашем примере smile):
Код

   <xsl:template match="/">
      <xsl:for-each select="/root/parent">
         <xsl:for-each select="child">
              <xsl:value-of select="concat(count(preceding::node()[name()='child'])+1, ') ', ., '&#xA;')" />
         </xsl:for-each>
      </xsl:for-each>
   </xsl:template>

Цитата(Royan @  6.6.2006,  20:14 Найти цитируемый пост)
Но моя проблема отличается тем, что я уже сделал выборку по parent и мне очень важно ее сохранить.

Вопрос - а обязательно ли ее сохранять?
Может стоит пересмотреть подход и переделать?
В чем исходная задача?    

Автор: Beard 8.6.2006, 21:59
Немного улучшил свой вариант:
Код

   <xsl:template match="/">
      <xsl:for-each select="/root/parent">
        <xsl:variable name = "precedingChildCount" select = "count(preceding-sibling::node()/child)"/>    
         <xsl:for-each select="child">
             <xsl:value-of select="concat($precedingChildCount+position(), ') ', ., '&#xA;')" />
         </xsl:for-each>
      </xsl:for-each>
   </xsl:template>

Другие варианты в голову что-то не лезят 

Автор: Royan 9.6.2006, 15:59
Цитата

Этот пример не может работать - дважды встречается переменная desiredPosition (опечатка,видимо)

Нет, не опечатка все зависит от парсера (я пользуюсь Xerces 2.7.1). Если посмотреть внимательно, то переменная инициализируется единственный раз и парсер вполне в состоянии разобраться с областью видимости и инициализацией.
За пример огромное спасибо - это действительно то, что нужно!


 

Автор: Beard 9.6.2006, 16:04
Цитата(Royan @  9.6.2006,  15:59 Найти цитируемый пост)
Нет, не опечатка все зависит от парсера (я пользуюсь Xerces 2.7.1)


Я просто это увидел
Код

<?xml-stylesheet type='text/xsl' href='test.xslt'?>

и подумал, что MSXML, который с областью видимости не справляется smile

Цитата(Royan @  9.6.2006,  15:59 Найти цитируемый пост)
За пример огромное спасибо - это действительно то, что нужно!

Не за что!
 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)