foo: längste string-length() ermitteln

Hallo,

ich bin noch ziemlich neu in dieser Materie und stehe vor meinem ersten großen Problem, zu dem ich leider bis jetzt keine Information gefunden habe. Hoffentlich ist es trotzdem lösbar.

Ich habe folgende XML Struktur:

<?xml version="1.0"?>
<tree>
    <node>
        <name>Menüpunkt 1</name>
    </node>
    <node>
        <name>Menüpunkt 2</name>
        <node>
            <name>Untermenüpunkt 1</name>
        </node>
        <node>
            <name>Langer Untermenüpunkt 2</name>
        </node>
    </node>
    <node>
        <name>Menüpunkt 3</name>
    </node>
</tree>

Ich möchte nun die längste string-length() des Attributs "name" unterhalb von "Menüpunkt 2" ermitteln. Das wäre in dem Fall "23". Wie gehe ich vor?

Vielen Dank für Eure Hilfe,
foo

  1. Noch einmal Hallo und ein Nachtrag zu meinem vorigen Posting:

    Versucht habe ich es bisher folgendermaßen:

    <xsl:template name="width" match=".">
    <xsl:for-each select=".">
      <xsl:sort select="string-length(name)" order="ascending"/>
      <xsl:value-of select="string-length(name[position=last()])"/>
    </xsl:for-each>
    </xsl:template>

    ... allerdings erfolglos, weil ich merkwürdigerweise immer "0" rausbekomme.

    Irgendwo hab ich wohl einen Denkfehler drin, nur leider komm ich gerade überhaupt nicht weiter.

    lg,
    foo

  2. Hallo,

    ich bin noch ziemlich neu in dieser Materie und stehe vor meinem ersten großen Problem, zu dem ich leider bis jetzt keine Information gefunden habe. Hoffentlich ist es trotzdem lösbar.

    Ich habe folgende XML Struktur:

    <?xml version="1.0"?>
    <tree>
        <node>
            <name>Menüpunkt 2</name>
            <node>
                <name>Untermenüpunkt 1</name>
            </node>
            <node>
                <name>Langer Untermenüpunkt 2</name>
            </node>
        </node>
    </tree>

    Ich möchte nun die längste string-length() des Attributs "name" unterhalb von "Menüpunkt 2" ermitteln. Das wäre in dem Fall "23". Wie gehe ich vor?

    Du hast kein einziges Attribut in deinem XML (mal von version="1.0" abgesehen).
    Wenn du deutsche Umlaute etc. in deinem XML verwendest, nimm
    <?xml version="1.0" encoding="iso-8859-1"?>

    Erstens definierst du einen Template:

    <xsl:template name="hoechste">
     <xsl:param name="knoten" />
     <xsl:if test="$knoten and not($knoten[string-length(.) != string-length(.)])">
      <xsl:variable name="max">
       <xsl:for-each select="$knoten">
        <xsl:sort select="string-length()" data-type="number" order="descending" />
        <xsl:if test="position() = 1">
         <xsl:value-of select="string-length(.)" />
        </xsl:if>
       </xsl:for-each>
      </xsl:variable>
      <xsl:value-of select="$knoten[string-length(.) = $max]" />
     </xsl:if>
    </xsl:template>

    Dann rufst du diesen Template dort auf wo du es benötigst und gibts beim Aufruf die Knoten bekannt, von dem der Höchste ausgewählt werdensoll.

    <xsl:call-template name="hoechste">
     <xsl:with-param name="knoten" select="//name[parent::node[preceding-sibling::name[text() = 'Menüpunkt 2']]]" />
    </xsl:call-template>

    Auf dein XML-Angewendet:
    <?xml version="1.0" encoding="iso-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/tree">
    <html>
    <head>
     <title>Untitled</title>
    </head>

    <body>
     <h1>
      <xsl:call-template name="hoechste">
       <xsl:with-param name="knoten" select="//name[parent::node[preceding-sibling::name[text() = 'Menüpunkt 2']]]" />
      </xsl:call-template>
     </h1>

    </body>
    </html>
    </xsl:template>

    <xsl:template name="hoechste">
     <xsl:param name="knoten" />
     <xsl:if test="$knoten and not($knoten[string-length(.) != string-length(.)])">
      <xsl:variable name="max">
       <xsl:for-each select="$knoten">
        <xsl:sort select="string-length()" data-type="number" order="descending" />
        <xsl:if test="position() = 1">
         <xsl:value-of select="string-length(.)" />
        </xsl:if>
       </xsl:for-each>
      </xsl:variable>
      <xsl:value-of select="$knoten[string-length(.) = $max]" />
     </xsl:if>
    </xsl:template>

    </xsl:stylesheet>

    Grüße
    Thomas

    1. Hi,

      <xsl:if test="$knoten and not($knoten[string-length(.) != string-length(.)])">

      Häh?

      string-length(.) != string-length(.)
      sollte doch nie zutreffen, da ein Wert seltenst ungleich zu sich selbst ist...
      Demnach wäre $knoten[string-length(.) != string-length(.)] immer leer (bzw. als boolean gesehen immer false)
      womit not($knoten[string-length(.) != string-length(.)]) eigentlich immer true sein sollte.

      Obiges wäre m.E. also äquivalent zu
      <xsl:if test="$knoten and true">
      bzw.
      <xsl:if test="$knoten">

      Oder hab ich da einen Denkfehler?

      cu,
      Andreas

      --
      Der Optimist: Das Glas  ist halbvoll.  - Der Pessimist: Das Glas ist halbleer. - Der Ingenieur: Das Glas ist doppelt so groß wie nötig.
      http://mud-guard.de/? http://www.andreas-waechter.de/ http://www.helpers.de/
      1. Hallo andreas,

        <xsl:if test="$knoten and not($knoten[string-length(.) != string-length(.)])">

        Häh?

        *lol*

        string-length(.) != string-length(.)
        sollte doch nie zutreffen, da ein Wert seltenst ungleich zu sich selbst ist...
        Oder hab ich da einen Denkfehler?

        Eigentlich stammt das aus einem Template, wo ich explizit einen komplizierteren Vergleich für Nummer brauche. Ich habe hier nur paar unnötige Teile gelöscht ( Aber offenbar nicht alles ;-)) und ersetzt.
        Klar hier geht es auch mit nur einem  <xsl:if test="$knoten">

        Grüße
        Thomas

        1. Hi,

          Eigentlich stammt das aus einem Template, wo ich explizit einen komplizierteren Vergleich für Nummer brauche. Ich habe hier nur paar unnötige Teile gelöscht ( Aber offenbar nicht alles ;-)) und ersetzt.
          Klar hier geht es auch mit nur einem  <xsl:if test="$knoten">

          Dann bin ich ja beruhigt - ich hatte schon über irgendwelche Nebenwirkungen von vielleicht nicht-existenten Strings nachgedacht, kam aber immer wieder zu dem Schluß, daß das sich ja auch wieder auf beiden Seiten des != gleich auswirken müßte...

          PS: "Einsteigerseminar XSLT" gefällt mir gut!

          cu,
          Andreas

          --
          Der Optimist: Das Glas  ist halbvoll.  - Der Pessimist: Das Glas ist halbleer. - Der Ingenieur: Das Glas ist doppelt so groß wie nötig.
          http://mud-guard.de/? http://www.andreas-waechter.de/ http://www.helpers.de/
          1. Hallo Andreas,

            PS: "Einsteigerseminar XSLT" gefällt mir gut!

            Das sagen sicher biede Autoren "Danke, das freut uns!" ;-)

            Grüße
            Thomas