XSLT - предыдущие узлы через предков, неправильно подсчитываемые - PullRequest
0 голосов
/ 17 июля 2011

У меня есть какой-то XML, подобный следующему:

<layout>
    <table>
            <tbody>
                    <tr>
                            <ref id="stock1" class="pile stock"/>
                    </tr>
                    <tr>
                            <ref id="cascade1" class="pile"/>
                            <ref id="cascade2" class="pile"/>
                    </tr>
            </tbody>
    </table>
</layout>

Я пытаюсь подсчитать, сколько карт было использовано предыдущими ref с, потому что каждая ref указывает на другой тег в другом месте документа, который имеет card дочерних элементов.

<xsl:variable name="curPos" select="position()"/>
<!-- Layout could change, not guaranteed previous ref is in same parent node as
     current ref, or at the same depth. -->
<xsl:variable name="prevRefID"
  select="/layout//*/ref[position() &lt; $curPos]/@id"/>
<xsl:variable name="numCardsPrevUsed"
  select="count(/cardHolder/*[@id = $prevRefID]/card)"/>

Проблема в том, что я не всегда получаю правильное количество ранее использованных карт. Когда на ref 'stock1', он правильно говорит, что 0 карт уже использовалось, но когда он достигает ref 'cascade1', он по-прежнему говорит, что 0 карт было использовано, хотя ref 'stock1' использует 24 карты. Затем, когда он достигает ref 'cascade2', он внезапно говорит, что было использовано 25 карт, что является правильным (24 в 'stock1' + 1 в 'cascade1'). Почему количество ранее использованных карт неверно в ref 'cascade1'?

Редактировать: yikes, вот пример XML:

<game name="Klondike">
  <layout>
    <table>
        <tbody>
            <tr>
                <ref id="stock1" class="pile stock"/>
                <ref id="waste1" colspan="2" class="empty-pile"/>
                <ref id="foundation1" class="empty-pile"/>
                <ref id="foundation2" class="empty-pile"/>
                <ref id="foundation3" class="empty-pile"/>
                <ref id="foundation4" class="empty-pile"/>
            </tr>
            <tr>
                <ref id="cascade1" class="pile"/>
                <ref id="cascade2" class="pile"/>
                <ref id="cascade3" class="pile"/>
                <ref id="cascade4" class="pile"/>
                <ref id="cascade5" class="pile"/>
                <ref id="cascade6" class="pile"/>
                <ref id="cascade7" class="pile"/>
            </tr>
        </tbody>
    </table>
  </layout>
  <state id="start">
    <foundation id="foundation1" />
    <foundation id="foundation2" />
    <foundation id="foundation3" />
    <foundation id="foundation4" />
    <cascade id="cascade1">
      <card suit="random" number="random" faceup="true"/>
    </cascade>
    <cascade id="cascade2">
      <card suit="random" number="random"/>
      <card suit="random" number="random" faceup="true"/>
    </cascade>
    ...other cascades...
    <waste id="waste1" />
    <stock id="stock1">
      <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
        <card suit="random" number="random"/>
    </stock>
  </state>
</game>

1 Ответ

1 голос
/ 17 июля 2011

Я думаю, что все зависит от текущего контекста шаблона, в котором находится фрагмент вашего кода, и последующего неправильного использования position().Приведенный выше фрагмент отлично работает, если вы итерируете на ref узлах, нет, если вы совпадаете на них .

Например, в этой ситуации:

 <xsl:template match="//ref">
 <!-- your fragment -->
 </xsl:template>

ваш код никогда не будет работать, потому что postion() не , очевидно прогрессивный .Вы должны использовать что-то вроде:

    <xsl:variable name="curPos" 
                  select="count(../preceding-sibling::tr/ref 
                                | preceding-sibling::ref)"/>
    <xsl:value-of select="$curPos"/>
        <xsl:variable name="prevRefID"
            select="//layout//*/ref
                    [count(preceding-sibling::ref) &lt; $curPos]/@id"/>

или лучше, измените контекст шаблона, чтобы вы могли использовать position().

...