MudGuard: XPath-Ausdruck: Element mit id 0, wenn nicht vorhanden, mit id 1

Hi,

ich hab XMLs von diesem Aussehen (auf's Wesentliche reduziert):

<root>
  <partner>
    <id>7</id>
    <name>seven</name>
  </partner>
  <partner>
    <id>1</id>
    <name>one</name>
  </partner>
  <partner>
    <id>0</id>
    <name>zero</name>
  </partner>
</root>

Es können wesentlich mehr partner-Elemente vorhanden sein, aber mindestens 1.
Die IDs sind immer positive Ganzzahlen.
Die Elemente sind unsortiert, ich kann also nicht einfach das erste partner-Element nehmen.

Dazu brauche ich jetzt den name, aus dem Element mit der niedrigsten id, falls die id entweder 0 oder 1 ist.

/root/partner[./id = 1]/name gibt mir 'one',
/root/partner[./id = 0]/name gibt mir 'zero',
falls beide vorhanden sind.

Aber das Kombinieren bekomm ich noch nicht hin, hab auch keine Idee dazu.

cu,
Andreas a/k/a MudGuard

  1. Hallo Andreas,

    mit XPath ab 2.0:

    /root/partner[id = min(//id)]/name -> zero
    
    

    Grüße,
    Thomas

    1. Hi,

      woher wußte ich nur, daß Du antworten wirst?

      mit XPath ab 2.0:

      /root/partner[id = min(//id)]/name -> zero
      
      

      hm.

      javax.xml.transform.TransformerException: Die Funktion konnte nicht gefunden werden: min

      Scheint wohl kein 2.0 zu können ... 😟

      cu,
      Andreas a/k/a MudGuard

      1. Hi,

        Scheint wohl kein 2.0 zu können ... 😟

        ja, auch in relativ aktuellem Java 17 wird in der XPath-Javadoc auf die Version 1.0 von XPath verwiesen.

        Naja, die 2.0 ist ja erst gut 12 Jahre alt …

        Trotzdem natürlich Danke für Deine Mühe! Hab ich in der ersten Antwort vergessen.

        cu,
        Andreas a/k/a MudGuard

        1. Naja, die 2.0 ist ja erst gut 12 Jahre alt …

          16 (01/2007)

          Grüße,
          Thomas

          1. Hi,

            Naja, die 2.0 ist ja erst gut 12 Jahre alt …

            16 (01/2007)

            das macht's auch nicht besser. Ich hatte 12/2010 von hier: XPath Cover Page

            cu,
            Andreas a/k/a MudGuard

            1. Hallo Andreas,

              das macht's auch nicht besser. Ich hatte 12/2010 von hier: XPath Cover Page

              Ok, ist die Second Edition.

              Habe über einige Neuerungen zeitnah berichtet. 😀

              Grüße,
              Thomas

      2. @@MudGuard

        woher wußte ich nur, daß Du antworten wirst?

        Wenn du das nicht willst, darfst du nicht „xml“ taggen. 🤪

        🖖 Живіть довго і процвітайте

        --
        „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
        — @Grantscheam auf Twitter
        1. Hi,

          woher wußte ich nur, daß Du antworten wirst?

          Wenn du das nicht willst, darfst du nicht „xml“ taggen. 🤪

          Von "Nicht-Wollen" kann gar keine Rede sein, es war eher ein "Hoffen".

          cu,
          Andreas a/k/a MudGuard

          1. @@MudGuard

            woher wußte ich nur, daß Du antworten wirst?

            Wenn du das nicht willst, darfst du nicht „xml“ taggen. 🤪

            Von "Nicht-Wollen" kann gar keine Rede sein, es war eher ein "Hoffen".

            Natürlich. Sollte ich je wieder eine Frage zu XSLT/XPath haben (die letzte ist schon ein Weilchen her), würde ich sie hier stellen in der Hoffnung, dass ThomasM drauf anspringt.

            🖖 Живіть довго і процвітайте

            --
            „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
            — @Grantscheam auf Twitter
      3. Hallo Andreas,

        javax.xml.transform.TransformerException: Die Funktion konnte nicht gefunden werden: min

        Scheint wohl kein 2.0 zu können ... 😟

        Dann auf die härtere Tour über die sibling-Achsen:

        /root/partner[id = /root/partner[not(preceding-sibling::partner/id &lt;= id) and not(following-sibling::partner/id &lt; id)]/id]/name
        
        

        Grüße,
        Thomas

        1. Hi,

          /root/partner[id = /root/partner[not(preceding-sibling::partner/id &lt;= id) and not(following-sibling::partner/id &lt; id)]/id]/name
          
          

          wie soll denn ein UnThomasM auf sowas kommen?

          Hat zwar beim ersten Versuch ne Exception geworfen, aber Du hast das wohl für den Einsatz in XSLT geschrieben - nach Ersatz der &lt; durch < hat's dann getan.

          Und mit der Ergänzung and (id <= 1) liefert es dann auch brav NIX, wenn weder eine 0 noch eine 1 vorhanden ist.

          Ganz lieben Dank für Deine Hilfe!

          cu,
          Andreas a/k/a MudGuard

        2. Ohne die Sibling-Achsen:

          <xsl:for-each select="partner">
            <xsl:sort select="number(id)" order="ascending"/>
            <xsl:if test="position() = 1">
              <xsl:copy-of select="."/>
            </xsl:if>
          </xsl:for-each>
          

          Cheers! David

          1. Hi,

            Ohne die Sibling-Achsen:

            <xsl:for-each select="partner">
              <xsl:sort select="number(id)" order="ascending"/>
              <xsl:if test="position() = 1">
                <xsl:copy-of select="."/>
              </xsl:if>
            </xsl:for-each>
            

            das ist aber kein XPath-Ausdruck. Es geht auch nicht um XSLT.

            Es geht nur um XPath 1.0.

            cu,
            Andreas a/k/a MudGuard