Text im Text suchen

Startseite Foren Deutsches LiveCode-Forum Text im Text suchen

Schlagwörter: 

Ansicht von 13 Antwort-Themen
  • Autor
    Beiträge
    • #21840
      Gil
      Teilnehmer

        hi,

        wie kann ich in LC in einem Text nach einer bestimmten Zeichenkette suchen?

        Am Besten per Beispiel:

        Es wird ein Smarthome-System abgefragt. Diese gibt einen (XML)-Text zurück:

        device name=”Fenster Büro” device_id=”4711″
        state ise_id=”2881″ value “1”
        bla bla…
        device
        device name “Fenster Wohnzimmer” device_id=”4712″
        blabla

        state ise_id=”2695″ value “2”
        bla bla

        device

        Nun möchte ich nach “state ise_id=”2695” suchen.
        Die folgenden Werte in der Zeile wie value benötige ich auch.

        Wie bekomme ich das am Besten hin?
        Frage ich die Werte alle einzeln ab, kollabiert die Smarthome-Zentrale wegen zu vieler Anfragen.
        hmm.

        Danke vorab und liebe Grüße
        Gil

      • #21844
        Torsten
        Teilnehmer

          Hi Gil,

          verstehe ich richtig, dass Du eine XML-Datei hast und darin suchst?
          Wobei Dein Beispieltext ja kein XML ist?

          Wie dem auch sei, wenn Deine Info in derselben Zeile wie der Suchbegriff ist, dann kannst Du es einfach so machen:

          put line lineoffset("state ise_id=" & quote & "2695" & quote, tDieXMLDatei) of tDieXMLDatei into tDieGesuchteZeile

          Jetzt hast Du in tDieGesuchteZeile die Zeile state ise_id="2695" value "2" drin.
          Wenn Du jetzt an den Wert von value ran willst, kannst Du es Dir einfach machen, falls das Schema immer gleich bleibt:

          set itemdelimiter to quote
          put item 4 of tDieGesuchteZeile into tValue

          Das funktioniert aber nur, wenn der Wert von value immer genau an dieser Stelle steht und keine anderen Parameter dazwischen stehen. Falls das der Fall sein sollte, kannst Du folgendes machen:

          set itemdelimiter to "value " & quote -- das Leerzeichen ist wichtig, da der String ja value "2" heisst
          put trueword 1 of item 2 of tDieGesuchteZeile into tValue

          Teste das mal aus, bei mir geht es so.

          Happy Coding
          Torsten

        • #21850
          Gil
          Teilnehmer

            hi Torsten,

            vielen Dank für die schnelle Antwort.
            Ich habe das Script ausprobiert – ét voila: es funktioniert, danke!

            Leider tut sich ein anderes Problem auf:

            Wenn das XML ausgelesen wird, besteht es aus einer einzigen Zeile.
            Also nicht so schön (Zeile für Zeile) wie z.B. im Browser oder mit Notepad++

            Anbei mein Script, wie ich die Daten aus der CCU (Smarthome-Zentrale) hole:

            on mouseDown pButtonNumber
               --tsNet initialisieren
               tsNetInit
               
               -- Zertifikat deaktiveren:
               tsNetVerifySSLPeer false
               
               put true into tSettings["force_digest_auth"]
               put "" into tSettings["username"]
               put "" into tSettings["password"]
               
               put tsNetGetSync("http://192.168.178.57/config/xmlapi/statelist.cgi", tHeaders, tRecvHeaders, tResult, tBytes) into tData
               
               put tData into fld "Info"
               
            end mouseDown
            

            Vielleicht hast Du noch einen Rat.

            Viele GRüße
            Gil

          • #21853
            Klaus Major
            Administrator

              Poste doch mal den langen String hier!

            • #21857
              Gil
              Teilnehmer

                hi Klaus,

                wie Du meinst:


                <?xml version=”1.0″ encoding=”ISO-8859-1″ ?><state><datapoint ise_id=’4715′ value=’0’/><datapoint ise_id=’2995′ value=’0’/><datapoint ise_id=’4459′ value=’0’/></state>

                viel Spaß 🙂

              • #21858
                Gil
                Teilnehmer

                  würde es den gehen, wenn man hinter jedem “>” ein “Return” einbauen kann?
                  Damit wäre es dann wieder Zeile für Zeile…

                • #21859
                  Klaus Major
                  Administrator

                    Danke, aber es heisst DENN, würde es DENN gehen. Wie man’s spricht!

                    Ja, das sollte klappen:

                    ...
                    replace ">" with (">" & CR) in tXMLString
                    ...

                    Dann kannst Du wieder mit Torstens Skript nach der gesuchten Zeile gucken.

                  • #21861
                    Gil
                    Teilnehmer

                      hi Klaus,
                      immer diese Rechtschreibfehler…

                      Klasse! Hat funktioniert!!!

                      Ganz liebe Grüße und tausend Dank!

                      Gil

                    • #21864
                      Axwald
                      Teilnehmer

                        Hallo,

                        für solche Fälle (Suche nach Werten innerhalb von bestimmten Tags) habe ich mir mal eine Funktion geschrieben – es kommt ja häufiger vor, daß die Daten in einem Wust an redundanten Tags versteckt sind.

                        Mit dem Beispiel von oben sieht das dann so aus:

                        on mouseUp
                           put "<?xml version='1.0' encoding='ISO-8859-1' ?>" & \
                                 "<state><datapoint ise_id='4715' value='0'/>" & \
                                 "<datapoint ise_id='2995' value='0'/>" & \
                                 "<datapoint ise_id='4459' value='0'/>" & \
                                 "</state>" into myData                             --  Daten laden
                           put "2995" into myStrg                                   --  Gesucht
                           put 0 into myCnt                                         --  Zähler
                           
                           repeat until (the controlKey is down)                    --  Schleife mit Sicherheit ...
                              put inBeet(myData,"datapoint ise_id='","'/>",myCnt) into myVar
                              if myVar is empty then                                --  Nix mehr da, fertig!
                                 exit repeat
                              else
                                 put line 1 of myVar into myCnt                      --  von hier aus weitersuchen ...
                                 if line 2 of myVar begins with myStrg then          --  ist es das Richtige?
                                    put line 2 of myVar & CR after myRes              --  dann merken
                                 end if
                              end if 
                           end repeat
                           answer information char 1 to -2 of myRes titled "Ergebnis:"  --  Antworten
                        end mouseUp
                        
                        function inBeet theString, theStart, theEnd, offNum
                           /* inBeet() is a very fast function to find things - 
                           It extracts data from "theString" that are between "theStart" and "theEnd",
                           and returns the first hit. If it doesn't find a match,
                           it returns empty.   
                           2 modes of action, depending on the value of "offNum" (see below).
                           
                           # theString (String): The data you're searching in. This can be huge :)
                           
                           # theStart, theEnd (String): what is before and after your desired text
                           .  (it is assumed that theEnd comes AFTER theStart, and that both are not empty ...)
                           
                           # OffNum (Int, optional) allows you to skip [offNum] chars at the beginning of theString
                           . When empty, it just returns the first found string, or empty;
                           . Else (offNum => 0) it returns a 2-line result:
                           .   line 1 is the position of the last char touched in theString (= last char found of theEnd).
                           .   And line 2 is the found string.
                           
                           What negative values do for offNum is left as an exercise - it has a (strange) use too!  
                           GPL V3, axwald @ forums.livecode.com 2020   */
                           
                           if offNum is not empty then
                              put offset(theStart,theString,offNum) + len(theStart) + offNum into myStart
                              if myStart is (len(theStart) + offNum) then return empty
                              put offset(theEnd,theString,myStart) + (myStart)-1 into myEnd
                              if myEnd is (myStart)-1 then return empty
                              return myEnd & CR & char myStart to myEnd of theString
                           else
                              return char (offset(theStart,theString) + len(theStart)) to \
                                    (offset(theEnd,theString,(offset(theStart,theString) + len(theStart))) \
                                    + (offset(theStart,theString) + len(theStart))-1) \
                                    of theString
                           end if
                        end inBeet

                        Das findet alle Vorkommen von “datapoint ise_id=’2995” und listet sie auf:

                        2995' value='0
                        2995' value='1

                        (Wenn es den 2ten gäbe – mit o.a. Daten kommt nur die erste Zeile.)

                        Wenn Du weißt, daß es nur ein “2995” gibt, dann geht es auch so:
                        answer information inBeet(myData,"datapoint ise_id='2995' value='","'/>") titled "Ergebnis:"
                        Das findet den ersten Wert zu “2995”: “0”

                        Viel Spaß!

                      • #21868
                        Gil
                        Teilnehmer

                          hi Axwald,

                          coooooool – diesmal bewusst mit Rechtschreibfehler 🙂

                          Danke und viele Grüße
                          Gil

                          PS: ja die Antwort der Homematic CCU ist recht üppig, wenn man nicht gezielt abfragt.
                          Da ist Dein Tool echt klasse.

                        • #21869
                          Gil
                          Teilnehmer

                            hi Axwald,

                            irgendwie will es bei mir nicht mit einer komplexeren XML.
                            Hier ein Auszug:


                            <device name=”Büro Fenster” ise_id=”2950″ unreach=”false” sticky_unreach=”false” config_pending=”false”>
                            <channel name=”Büro Fenster:0″ ise_id=”2951″ visible=”” operate=””>
                            <datapoint name=”BidCos-RF.IEQ0205608:0.UNREACH” type=”UNREACH” ise_id=”2967″ value=”false” valuetype=”2″ valueunit=”” timestamp=”1595149763″ operations=”5″/>
                            <datapoint name=”BidCos-RF.IEQ0205608:0.STICKY_UNREACH” type=”STICKY_UNREACH” ise_id=”2963″ value=”false” valuetype=”2″ valueunit=”” timestamp=”1595149763″ operations=”7″/>
                            <datapoint name=”BidCos-RF.IEQ0205608:0.CONFIG_PENDING” type=”CONFIG_PENDING” ise_id=”2953″ value=”false” valuetype=”2″ valueunit=”” timestamp=”1595149763″ operations=”5″/>
                            <datapoint name=”BidCos-RF.IEQ0205608:0.LOWBAT” type=”LOWBAT” ise_id=”2957″ value=”false” valuetype=”2″ valueunit=”” timestamp=”1595340388″ operations=”5″/>
                            <datapoint name=”BidCos-RF.IEQ0205608:0.RSSI_DEVICE” type=”RSSI_DEVICE” ise_id=”2961″ value=”1″ valuetype=”8″ valueunit=”” timestamp=”1595149763″ operations=”5″/>
                            <datapoint name=”BidCos-RF.IEQ0205608:0.RSSI_PEER” type=”RSSI_PEER” ise_id=”2962″ value=”209″ valuetype=”8″ valueunit=”” timestamp=”1595149763″ operations=”5″/>
                            </channel>
                            <channel name=”Büro Fenster” ise_id=”2971″ visible=”true” operate=”true”>
                            <datapoint name=”BidCos-RF.IEQ0205608:1.STATE” type=”STATE” ise_id=”2995″ value=”0″ valuetype=”16″ valueunit=”” timestamp=”1595426260″ operations=”5″/>
                            <datapoint name=”BidCos-RF.IEQ0205608:1.ERROR” type=”ERROR” ise_id=”2972″ value=”0″ valuetype=”16″ valueunit=”” timestamp=”1595426260″ operations=”5″/>
                            <datapoint name=”BidCos-RF.IEQ0205608:1.LOWBAT” type=”LOWBAT” ise_id=”3644″ value=”false” valuetype=”2″ valueunit=”” timestamp=”1595426260″ operations=”5″/>
                            </channel>
                            </device>
                            <device name=”Büro Heizung” ise_id=”1607″ unreach=”false” sticky_unreach=”false” config_pending=”false”>
                            <channel name=”Büro Heizung:0″ ise_id=”1608″ visible=”” operate=””>
                            <datapoint name=”BidCos-RF.JEQ0233943:0.UNREACH” type=”UNREACH” ise_id=”1623″ value=”false” valuetype=”2″ valueunit=”” timestamp=”1595149763″ operations=”5″/>
                            <datapoint name=”BidCos-RF.JEQ0233943:0.STICKY_UNREACH” type=”STICKY_UNREACH” ise_id=”1619″ value=”false” valuetype=”2″ valueunit=”” timestamp=”1595149763″ operations=”7″/>
                            <datapoint name=”BidCos-RF.JEQ0233943:0.CONFIG_PENDING” type=”CONFIG_PENDING” ise_id=”1609″ value=”false” valuetype=”2″ valueunit=”” timestamp=”1595149763″ operations=”5″/>
                            <datapoint name=”BidCos-RF.JEQ0233943:0.LOWBAT” type=”LOWBAT” ise_id=”1613″ value=”false” valuetype=”2″ valueunit=”” timestamp=”1595149763″ operations=”5″/>
                            <datapoint name=”BidCos-RF.JEQ0233943:0.RSSI_DEVICE” type=”RSSI_DEVICE” ise_id=”1617″ value=”1″ valuetype=”8″ valueunit=”” timestamp=”1595149763″ operations=”5″/>
                            <datapoint name=”BidCos-RF.JEQ0233943:0.RSSI_PEER” type=”RSSI_PEER” ise_id=”1618″ value=”195″ valuetype=”8″ valueunit=”” timestamp=”1595149763″ operations=”5″/>
                            </channel>
                            <channel name=”Büro Heizung” ise_id=”1627″ visible=”true” operate=”true”>
                            <datapoint name=”BidCos-RF.JEQ0233943:1.VALVE_STATE” type=”VALVE_STATE” ise_id=”1641″ value=”0″ valuetype=”16″ valueunit=”%” timestamp=”1595431247″ operations=”5″/>
                            <datapoint name=”BidCos-RF.JEQ0233943:1.ERROR” type=”ERROR” ise_id=”1628″ value=”0″ valuetype=”16″ valueunit=”” timestamp=”1595431247″ operations=”5″/>
                            </channel>
                            </device>

                            Hier möchte ich zum den Datenpunkt (datapoint_id) 2995 abfragen.

                            Vermutlich ist es das “End-Tag” – oder?

                            LG
                            Gil

                          • #21872
                            Klaus Major
                            Administrator

                              Hi Gil,

                              bei solchen komplexen XML-Dateien lohnt es sich sicher, mal einen Blick auf das XML External von LC zu werfen. Nicht so einfach in der Bedienung, aber sehr mächtig!

                              Hier gibt es eine Lektion dazu von LC:
                              http://lessons.livecode.com/m/4071/l/7011-how-to-read-in-data-from-an-xml-file

                              Gruß

                              Klaus

                            • #21878
                              Axwald
                              Teilnehmer

                                Hallo,

                                wenn ich das recht interpretiere, geht es darum, ob das Büro-Fenster offen oder zu ist? (Typ ‘State’, Value “0” – geschlossen?)

                                Wir brauchen eindeutige Werte für “davor” und “danach”, also:

                                   put "C:/Users/myName/Desktop/state.txt" into myFile  --  dein Beispiel
                                   put URL ("file:" & myFile) into myData
                                   --  ise_id="2995" value="  | ist davor, also:
                                   put "ise_id=" & quote & "2995" & quote & " value=" & quote into myStart
                                   --  " valuetype            | kommt danach, also:
                                   put quote & " valuetype" into myEnd
                                   
                                   answer information "Value = " & inBeet(myData, myStart, myEnd) titled "Ergebnis:"
                                

                                Etwas frickelig, die Verkettung der Variablen mit den Quotes …

                                Viel Spaß!

                              • #21882
                                Gil
                                Teilnehmer

                                  hi @all,

                                  es läuft jetzt!
                                  Sowohl mit der Abfrage von Thorsten und der von Axwald!

                                  Besten Dank, Ihr Lieben!

                              Ansicht von 13 Antwort-Themen
                              • Du musst angemeldet sein, um auf dieses Thema antworten zu können.