FTUI Widget - XPath

help 32  Tester gesucht! Herunterladen, entpacken, testen, berichten, wünschen.

Hier mein FTUI Widget um XML, HTML oder auch andere Dateien auszulesen, welche auf der DOM-Struktur basieren.

Dieses Widget ist entstanden, weil moerte aus dem FHEM-Forum eine Möglichkeit gesucht hat, um die Vertretungspläne seiner Kinder in FTUI darstellen zu können. Natürlich nur die Klasse des Kindes betreffend.
Es basiert auf der Xpath-Syntax und stellt die Ergebnisse in einer frei formatierbaren Tabelle dar.

Es kann immer nur in einer "data-node" nach "data-find" gesucht werden, in denen "data-filter" vorkommt. Es werden aber alle "data-nodes", in denen "data-filter" vorkommt, ausgelesen und "data-find" angezeigt. Lässt man "data-filter" leer werden alle "data-find" aus allen "data-node" im Dokument angezeigt.
Diese Erklärung ist vielleicht etwas kompliziert. Besser erkennt man es an den Beispielen wie es funktioniert.

warning 32  Für dieses Widget ist ein eingerichtetes und Funktionierendes HTTPMOD-Device erfolderlich. Das Attribut "showBody" muss gesetzt sein!
Der Grund hierfür: Die XML-Dateien der Vertretungspläne, welche den Anlass zur Entstehung des Widgets gegeben haben, sind nicht über HTTPS abrufbar. Da viele FHEM-Installationen aber mit HTTPS abgesichert sind und in den meisten Browsern die Sicherheitseinstellungen es nicht zulassen HTTP-Inhalte nach HTTPS zu importieren, gehe ich den Umweg über HTTPMOD. Außerdem können so Aktualisierungen auch manuell angeschoben werden und es gibt einen einstellbaren Intervall zur automatischen Aktualisierung. Das spart Zeit und Code im Widget.

define <name> HTTPMOD <url-zur-datei> <interval>
attr <device> showBody 1
information 32  Es empfiehlt sich zudem ein userReading anzulegen, welches das Internal "httpbody" wiederspiegelt. Tut man dies nicht, werden die Daten in FTUI nur bei einem "shortpoll" (verzögert) aktualisiert.

attr <device> userReading <ReadingName> { InternalVal('<device>','httpbody','') }

 

data-device Dein HTTPMOD-Device in FHEM.
data-get Reading welches geholt werden soll. Standard: httpbody
Siehe Hinweis oben.
data-node Die "Node" in der gesucht werden soll. Es können beliebig viele im zu durchsuchenden Dokument vorkommen. XPath-Syntax beachten!
data-filter Um die "Node" nach gewissem Inhalt zu durchsuchen.
data-find Die anzuzeigenden Elemente aus den gefundenen "Nodes", welche durch "data-filter" gefiltert wurden. Kann ein Array sein.
data-max-result Noch ohne Funktion.
data-table-header Respektiv zu "data-find" die Spaltenüberschrift in der Tabelle, muss genau so viele Einträge wie "data-find" enthalten.
data-not-found Frei wählbarer Text, welcher angezeigt wird wenn keine Übereinstimmung gefunden wurde.
data-no-data Frei wählbarer Text, welcher angezeigt wird wenn keine Daten vorhanden sind. D.h. das Reading im Device leer oder nicht vorhanden ist. Hängt auch mit dem Attribut "showBody" zusammen.

 

Beispele:

Gegeben ist folgende XML-Datei als Reading im HTTPMOD-Device:

<?xml version="1.0" encoding="UTF-8"?>

<bookstore>
  <book>
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
  <book>
    <title lang="de">Herr der Ringe</title>
    <author>J. R. R. Tolkien</author>
    <year>1954</year>
    <price>34.49</price>
  </book>

</bookstore>

 

Wir wollen uns nun alle Bücher und alle Informationen anzeigen lassen (einfachste Variante).

<div data-type="xpath"
     data-device="HTTPMOD-Device"
     data-get="data"
     data-node="//book"  <!--Hier ist XPath-Syntax für nodes anzuwenden.-->
     data-filter=""  <!--leer-->
     data-find='["title","author","year","price"]'  <!--Das ist ein FTUI-Array.-->
     data-table-header='["Titel","Author","Jahr","Preis"]'>  <!--Das ist ein FTUI-Array.-->
</div>

Die Ausgabe sollte in etwa wie folgt aussehen:

Titel Author Jahr  Preis
Harry Potter J K. Rowling 2005 29.99
Herr der Ringe J. R. R. Tolkien 1954 34.49

 

Im nächsten Beispiel wollen wir nur Bücher des Author's "J. R. R. Tolkien" angezeigt bekommen.

<div data-type="xpath"
     data-device="HTTPMOD-Device"
     data-get="data"
     data-node="//book"
     data-filter="[author, 'J. R. R. Tolkien']"  <!--Das ist kein FTUI-Array. Das ist XPath-Syntax-->
     data-find='["title","author","year","price"]'  <!--Das ist ein FTUI-Array.-->
     data-table-header='["Titel","Author","Jahr","Preis"]'>  <!--Das ist ein FTUI-Array-->
</div>

Die Ausgabe sollte in etwa wie folgt aussehen:

Titel Author Jahr  Preis
Herr der Ringe J. R. R. Tolkien 1954 34.49

 

In diesem Beispiel wollen wir das Buch von J K. Rowling. Wir suchen aber nur nach "Rowling" und wollen nur das Jahr und Preis anzeigen:

<div data-type="xpath"
     data-device="HTTPMOD-Device"
     data-get="data"
     data-node="//book"  <!--Hier ist XPath-Syntax für nodes anzuwenden.-->
     data-filter="[contains(author, 'Rowling')]"  <!--Das ist kein FTUI-Array. Das ist XPath-Syntax-->
     data-find='["year","price"]'  <!--Das ist ein FTUI-Array.-->
     data-table-header='["Jahr","Preis"]'>  <!--Das ist ein FTUI-Array-->
</div>

warning 32  Bei den Parametern immer auf die Groß- und Kleinschreibung achten!

Die Ausgabe sollte in etwa wie folgt aussehen:

Jahr  Preis
2005 29.99

 

Weitere Beispiele werden folgen...

 

Tabellenformatierung:

Die Tabelle wird so aufgebaut, dass jede Zelle eindeutig identifiziert werden kann.
Wenn man dem umgebenden div-Element eine ID gibt (<div data-type="xpath"... id="xpathid"></div>), kann auch die Tabelle selbst klar identifiziert werden.

<table>

<tr id="trh"> 
<th id="th0"><th id="th1"><th id="th2">...
<tr id="tr0"> 
<td id="td0"> <td id="td1"> <td id="td2"> ...
<tr id="tr1"> 
<td id="td0"> <td id="td1"> <td id="td2"> ...
<tr id="tr2"> 
... ... ... ...

</table>

 

Download: 

Datei Größe Datum
widget_xpath.zip 23.9 kB 11.02.2019
     

 

Grüße^^

 

Kommentare  

0 # DANKEMarkus 2019-02-11 15:33
Hallo mein Guter,
genau so hab ich mir das vorgestellt.
Hut ab für die tolle Arbeit und danke für die Zeit, die du dir dafür genommen hast.

Resümee: Läuft bei mir super!!!

So ein kleiner Spenden-Button auf deiner Webseite wäre nicht schlecht ;)

LG aus dem schönen Vogtland
Markus (moerte)
Antworten | Antworten mit Zitat | Zitieren