Startseite › Foren › Deutsches LiveCode-Forum › Text im Text suchen
Schlagwörter: Textsuche
- Dieses Thema hat 13 Antworten und 4 Teilnehmer, und wurde zuletzt aktualisiert vor 4 Jahren, 3 Monaten von Gil.
-
AutorBeiträge
-
-
Juli 20, 2020 um 20:41 Uhr #21840
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
…
deviceNun 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 -
Juli 20, 2020 um 22:24 Uhr #21844
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 -
Juli 21, 2020 um 16:01 Uhr #21850
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 -
Juli 21, 2020 um 16:12 Uhr #21853
Poste doch mal den langen String hier!
-
Juli 21, 2020 um 17:03 Uhr #21857
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ß 🙂
-
Juli 21, 2020 um 17:07 Uhr #21858
würde es den gehen, wenn man hinter jedem “>” ein “Return” einbauen kann?
Damit wäre es dann wieder Zeile für Zeile… -
Juli 21, 2020 um 17:16 Uhr #21859
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.
-
Juli 21, 2020 um 17:25 Uhr #21861
hi Klaus,
immer diese Rechtschreibfehler…Klasse! Hat funktioniert!!!
Ganz liebe Grüße und tausend Dank!
Gil
-
Juli 22, 2020 um 10:55 Uhr #21864
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ß!
-
Juli 22, 2020 um 17:07 Uhr #21868
hi Axwald,
coooooool – diesmal bewusst mit Rechtschreibfehler 🙂
Danke und viele Grüße
GilPS: ja die Antwort der Homematic CCU ist recht üppig, wenn man nicht gezielt abfragt.
Da ist Dein Tool echt klasse. -
Juli 22, 2020 um 17:40 Uhr #21869
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 -
Juli 22, 2020 um 18:32 Uhr #21872
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-fileGruß
Klaus
-
Juli 23, 2020 um 15:59 Uhr #21878
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ß!
-
Juli 25, 2020 um 18:19 Uhr #21882
hi @all,
es läuft jetzt!
Sowohl mit der Abfrage von Thorsten und der von Axwald!Besten Dank, Ihr Lieben!
-
-
AutorBeiträge
- Du musst angemeldet sein, um auf dieses Thema antworten zu können.