Alex Wolff: mit xpath einen knoten finden (for runaways ;)

hallo,
ich habe eine xml-datei mit ungefähr folgender struktur:

<htmlfolder>
  <htmlfolder>
    <isintopnav>
      <tppos>1</tppos>
    </isintopnav>
  </htmlfolder>
  <htmlfolder>
    <htmlfolder>
      <isintopnav>
        <tppos>2</tppos>
      </isintopnav>
      <htmlfolder marker="yes">
      </htmlfolder>
    </htmlfolder>
  </htmlfolder>
</htmlfolder>

man sieht: die <htmlfolder>-elemente können beliebig ineinander verschachtelt sein. manche der <htmlfolder>-elemente haben einen <isintopnav>-kindknoten. genau einer der <htmlfolder>-elemente ist markiert durch ein attribut mit namen "marker" (dessen wert "yes" ist nicht so wichtig, vorhandensein des attributs reicht).

jetzt möchte ich einer variablen den wert vom <tppos>-element aus dem markierten <htmlfolder>-element zuweisen.
problem dabei ist: wenn der markierte <htmlfolder> gar kein <isintopnav>-element hat, soll im baum aufwärts gesucht werden, bis man einen <htmlfolder> mit <isintopnav>-element gefunden hat. dann wird der wert dessen <tppos>-elements der variablen zugewiesen.
findet man jedoch bis zum obersten wurzelknoten kein <isintopnav>-element, soll die variable den wert '-1' bekommen.

meine XSL-lösung sieht so aus:

<xsl:variable name="varttn">
 xsl:choose
  <xsl:when test="boolean(//*[child::isintopnav]//*[@marker])">
   <xsl:for-each select="//*[child::isintopnav]//*[@marker]">
    xsl:choose
     <xsl:when test="(position() = last())and(last() != 0)">
      <xsl:value-of select="isintopnav/tppos" />
     </xsl:when>
    </xsl:choose>
   </xsl:for-each>
  </xsl:when>
  xsl:otherwise
   <xsl:value-of select="'-1'" />
  </xsl:otherwise>
 </xsl:choose>
</xsl:variable>

aber leider funktioniert es nicht; der xpath-ausdruck drückt nicht das aus, was ich meine.

hat jemand eine idee, wie man dieses problem lösen kann? bin für alle vorschläge sehr dankbar.
grüße, alex wolff

  1. leider noch keine antwort...

    ich hab mal versucht, einen anderen weg zu gehen, aber auch hier komme ich nicht zu dem gewünschten ergebnis:

    <xsl:variable name="varttn">
     <xsl:for-each select="//*[@marker]">
      xsl:choose
       <xsl:when test="boolean(./ancestor-or-self::*[child::isintopnav])">
        <xsl:for-each select="./ancestor-or-self::*[child::isintopnav]">
         <xsl:when test="position() = last()">
          <xsl:value-of select="./isintopnav/tppos" />
         </xsl:when>
        </xsl:for-each>
       </xsl:when>
       xsl:otherwise
        <xsl:value-of select="'-1'" />
       </xsl:otherwise>
      </xsl:choose>
     </xsl:for-each>
    </xsl:variable>

    was mache ich nur falsch? wer kann mir helfen?
    grüße, alex wolff
    p.s.: die abfrage (last() != 0) vom ersten versuch hätte ich mir sparen können, aber das war nicht der fehler...

    1. hoho, jetzt geht's!
      die zweite variante war schon ganz gut; der fehler war das when-element im when element. hab's durch ein if ersetzt.
      wen's interessiert:

      <xsl:variable name="varttn">
       <xsl:for-each select="//*[@marker]">
        xsl:choose
         <xsl:when test="boolean(ancestor-or-self::*[child::isintopnav])">
          <xsl:for-each select="ancestor-or-self::*[child::isintopnav]">
           <xsl:if test="position() = last()">
            <xsl:value-of select="isintopnav/tppos" />
           </xsl:if>
          </xsl:for-each>
         </xsl:when>
         xsl:otherwise
          <xsl:value-of select="'-1'" />
         </xsl:otherwise>
        </xsl:choose>
       </xsl:for-each>
      </xsl:variable>

      dank an alle beteiligten !]
      alex

      1. Hallo,

        Netter Monolog! ;-)

        Grüße
        Thomas