Frank (no reg): XPATH Expression (boolean check) & .Net

Servus,

ich hätte eine kleine Frage: ..

Vorliegend habe ich folgende Xml-Daten

  
<DSFund>  
 <Fund>  
   <Id>12345678</Id>  
   <Name>Cerberus Intl.</Name>  
   <Confidential>true</Confidential>  
 </Fund>  
 <!-- weitere Blöcke -->  
</DSFund>  

Ich möchte jetzt jeden Fund-Block auf das Element <Confidential> == true prüfen und wenn es true ist, auch true zurückbekommen.

Dazu habe ich folgendes XPath (beispielhaft für den 1sten Fund:
//Fund[1]/Confidential/text()

Wenn ich jetzt mit der XPath-Implementierung vom .Net Framework .Evaluate ausführe bekomme ich eine Art Node-Objekt zurück. Ich hätte aber lieber gern einen boolschen Wert. Packe ich bool(//Fund[1]/Confidential/text()) liefert es mir sensationellerweise immer true zurück auch wenn der Wert auf false steht. Wie kann ich XPath dazu bewegen mir gleich den richtigen Wert im richtigen Typen zurückzugeben (ich möchte nicht erst noch eine Vergleichsoperation in .net implementieren obgleich das nicht viel Arbeit wäre).

Danke für Anregungen :))

Ciao, Frank

  1. Hi,

    Ich möchte jetzt jeden Fund-Block auf das Element <Confidential> == true prüfen und wenn es true ist, auch true zurückbekommen.

    warum prüfst Du dann nur, ob ein Text da ist?

    Packe ich bool(//Fund[1]/Confidential/text()) liefert es mir sensationellerweise immer true zurück auch wenn der Wert auf false steht.

    Das liegt daran, dass der text() ein Text ist, kein Boole'scher Wert. "false" ist im Boole'schen Sinn ebenso wahr, wie es "Hausschuh" ist.

    Wie kann ich XPath dazu bewegen mir gleich den richtigen Wert im richtigen Typen zurückzugeben

    Vergleiche den Text mit demjenigen Text, der für Dich wahr bedeutet.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Servus,

      ich war davon ausgegangen, dass XPath ja ein eigenes unstriktes Typensystem hat und ja sowiesoschon ein boolscher Wert (false oder true) drin steht und ich den nur noch mit einer XPath-Funktion à la boolean() explizit als boolschen Wert kennzeichnen muss. Aber leider scheint es wohl, dass ich wirklich einen Vergleich auf ='true' oder ='false' durchführen muss. Dachte es ginge einfacher. :(

      Ciao, Frank

      1. Hi,

        ich war davon ausgegangen, dass XPath ja ein eigenes unstriktes Typensystem hat

        jau. Wieso propagierst Du diese Erkenntnis auf XML?

        und ja sowiesoschon ein boolscher Wert (false oder true) drin steht

        Nein, es steht ein Text drin. Text ist kein Boole'scher Wert.

        Aber leider scheint es wohl, dass ich wirklich einen Vergleich auf ='true' oder ='false' durchführen muss. Dachte es ginge einfacher. :(

        Och, so viel schwieriger ist das doch nun wirklich nicht :-)

        Cheatah

        --
        X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
        X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
        X-Will-Answer-Email: No
        X-Please-Search-Archive-First: Absolutely Yes
        1. Hi Cheatah,

          propaganda, was, wie? Ich benutze ja XPath und kein XML (haha ;)), und es (XPath) bietet ja so interessante eingebaute Funktionen wie not(), exists(), boolean(), ... uvm.

          Du hast ja recht, so viel schwieriger ist es ja nicht ... einfach nur ein paar Hochkommas setzen und dann funktioniert es. :))

          Danke für deine Unterstützung.
          Frank

          1. Tach Frank,

            propaganda, was, wie? Ich benutze ja XPath und kein XML (haha ;)), und es (XPath) bietet ja so interessante eingebaute Funktionen wie not(), exists(), boolean(), ... uvm.

            Wenn Deine Umgebung XSLT 2.0 / XPath 2.0 unterstützt, wäre eine eigene Funktion praktikabel:

              
            <?xml version="1.0" encoding="ISO-8859-1"?>  
            <xsl:stylesheet version="2.0"  
              xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
              xmlns:fn="http://www.w3.org/2005/xpath-functions"  
              xmlns:my="http://www.example.net/my"  
              exclude-result-prefixes="fn my">  
              
              <xsl:function name="my:bool">  
                <xsl:param name="test_str"/>  
                <xsl:sequence select="  
                  if($test_str='true')  
                  then fn:true()  
                  else (if($test_str='false') then fn:false() else())"/>  
              </xsl:function>  
              
              <xsl:template match="wurzel">  
                <xsl:value-of select="my:bool(bla/blub/text())"/>  
                <!--  
                <xsl:value-of select="fn:not(my:bool(bla/text()))"/>  
                -->  
              </xsl:template>  
              
            </xsl:stylesheet>
            

            Die Funktion gibt also true/false als Wahrheitswerte zurück, die sich dann auch weiter verarbeiten lassen, z. B. mittels fn:not() zu false/true negieren (wie im Kommentar ersichtlich).

            Man liest sich,
            svg4you

            1. Nachtrag:

              <!--
                  <xsl:value-of select="fn:not(my:bool(bla/text()))"/>
                  -->
                </xsl:template>

              Hier sollte natürlich auch bla/blub stehen, also:

              <xsl:value-of select="fn:not(my:bool(bla/blub/text()))"/>

              Man liest sich,
              svg4you

              1. Servus,

                danke für den Tip mit der eigenen Funktion, aber soviel Aufwand wollte ich nun auch nicht treiben und zudem benutze ich kein XSL(T), nur XPath. Der Vergleich des Strings ist da dann doch wohl die kürzeste, beste und schmerzloseste Methode :)

                Ciao, Frank