xmlApi Werte auslesen

Hallo

Ich hoffe ich bin hier richtig.

Ich stehe vor einem Problem. Ich möchte über eine XML-API-Schnittstelle mit einem Arduino(also vielmehr mit eienem ESP8266) eine Systemvariable meiner Hausautomatisierung abfragen und in einem float speichern. Hört sich ja erstmal nicht wild an.

Ich schreibe eine Systemvariable mit:

if(client.connect(HomaticIP,80))
{ client.print(" GET /config/xmlapi/statechange.cgi?ise_id=2632&new_value=");
client.print(variable1);
client.println(" HTTP/1.0");
client.println();
}

Das funktioniert wunderbar.
Nun versuche ich etwas wie dieses:

if (client.connect(HomematicIP,80)) {
client.println("GET /config/xmlapi/sysvar.cgi?ise_id=2632 HTTP/1.0\r\n");
while(client.available() == 0 ){
string1 = client.readString();
break;
}

Sie Antwort sieht dann so aus:

HTTP/1.0 200 OK
Content-Type: text/xml
Access-Control-Allow-Origin: *
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Robots-Tag: none
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Referrer-Policy: no-referrer
Content-Length: 300
Connection: close
Date: Fri, 19 Jun 2020 20:20:38 GMT

<?xml version="1.0" encoding="ISO-8859-1" ?>

Da steht meine 3.00000 als "Value".
Aber da gebe ich ja nun einen String aus. Kann mir vielleicht jemand veraten wie ich diese 3.000000 nun in eine float-Variable bekomme, sodass ich damit rechnen kann?

Vielen Dank im Voraus
Alex

(deleted)

schnigge5:
Ich stehe vor einem Problem. Ich möchte über eine XML-API-Schnittstelle mit einem Arduino(also vielmehr mit eienem ESP8266) eine Systemvariable meiner Hausautomatisierung abfragen und in einem float speichern.

Vielleicht hilft Dir ein parser:

Vielleicht hilft Dir ein parser:
GitHub - leethomason/tinyxml2: TinyXML2 is a simple, small, efficient, C++ XML parser that can be easily integrated into other programs.

also ich habe in den doc-ordner reingeschaut. Da gibt es sehr viele XML-Dateien aber leider keinen Beispielcode wie man die TinyXML anwendet. Also gaanz simple Beispiele die exemplarisch zeigen wie man ein bestimmtes Detail in den Gesamtdaten ehrauspickt.

du ermittelst in dem Gesamtstring die Position an der der Teilstring "Grube Stand" beginnt. (BeginPos)
du ermittelst in dem Gesamtstring die Position an der der Teilstring "value_list" beginnt. (Endpos)
Dann kopierst du aus dem Gesamtstring von Position BeginPos bis Position EndPos" die Zeichen in einen neue Stringvariable.

Anmerkung die Namen in Klammern sollen Variablennamen sein:

innerhalb der neuen Stringvariable die jetzt "Grube Stand' variable='3.000000' value='3.000000' value_list" enthält ermittelst du die Position von "value=" (ValuePos) und die Position von "value_list" (ValueListPos)
Dann kopierst du beginnend bei Position ValuePos + 7) bis Position ValueListPos - 1 in eine Stringvariable
Damit hast du dann die Zeichenfolge "3.000000" herausextrahiert. Und auf diese Zeichenfolge wendet man dann Umwandlung in einen float an.

global definierte Stringvariablen vom Typ String (geschrieben mit großen "S") führen über die Zeit dazu das der gesamte RAM verbraucht wird und dann Teile des Programms überschrieben werden. => Programm stürzt ab.

Deshalb entweder Variablen vom Typ "String" (String mit großen "S" nur innerhalb von functions verwenden die oft aufgerufen und wieder verlassen werden oder umsteigen auf c-string oder array of char oder PString (PString ist eine library)

Bei array of char muss der Array so groß definiert werden dass auch die längste mögliche Zeichenfolge hineinpasst.

PString ist beim Variablendefinieren ein bisschen umständlicher aber PString stellt 100% sicher das ein evtl. zu großer String einfach abgeschnitten wird. Damit wird sichergestellt das das Einlesen /Zuweisen eines zu großen Strings niemals zum Überschreiben von Speicher (=Absturz des Programmes) führt. Es gibt aber auch dann eine Stelle an der man sehr sorgfältig programmieren muss. Man benutzt den Befehl memcpy. Der kopiert einfach gnadenlos die angegebene Anzahl bytes. Wenn der Wert im Parameter "Anzahl bytes" zu groß ist würde man sich auch anderweitig vergebene Speicherbereiche überschreiben.

Weiter unten habe ich einem Pi-ma-Daumen-Besipielcode gepostest. Die ZIP-Datei im Attachment enthält such Kommentare

@the Community: Kennt denn jemand einen deutlich einfacheren Parser als dieses tinyXML bei dem Beispiele wie man den Parser benutzt ?

viele Grüße Stefan

StefanL38:
[]

[edit]Der Beitrag wurde inhaltlich angepasst; Das Quote kann so nicht stehen bleiben[/edit]
Warum schreist Du so?
Offensichtlich scheinen andere damit umgehen zu können.

Fehlt ein youtube tut?
10 Minuten - inclusive Anleitung zur Einbindung im lib-Ordner.

@ TO:

wirds immer nur die eine Variable nach dem Text:

value='

brauchen oder wirst du auch mal andere Werte benötigen?

@StefanL38: Ich finde Deine Ausdrucksweise für ein öffentliches Forum, wo auch Minderjährige mitlesen, absolut UNANGEMESSEN! Daher wiederhole ich Deinen Text bewußt nicht!

Außerdem scheint mir Deine Reaktion, selbst wenn sie zutreffen sollte, mit Großbuchstaben in Rot gänzlich überzogen. "Keine Beispiele finde ich blöd!" hätte genügt.

Ich bitte Dich daher, Deinen Text zu korrigieren!


schnigge5:
Ich hoffe ich bin hier richtig.

Klar doch!

schnigge5:
Da steht meine 3.00000 als "Value".
Aber da gebe ich ja nun einen String aus. Kann mir vielleicht jemand veraten wie ich diese 3.000000 nun in eine float-Variable bekomme, sodass ich damit rechnen kann?

Das hängt davon ab, wie unterschiedlich diese Antworten ausfallen können. Für genau Dein Beispiel eventuell so:

void setup() {
  Serial.begin(115200);
  Serial.println("Start");
  float wert = 0.0;
  String string1 = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?><systemVariables><systemVariable name='Grube Stand' variable='3.000000' value='3.123456' value_list='' value_text='' ise_id='2632' min='0' max='65000' unit='cm' type='4' subtype='0' timestamp='1592598038' value_name_0='' value_name_1=''/></systemVariables>";
  Serial.println(string1);
  uint16_t p = string1.indexOf("Grube Stand");
  if (p > 0) {
    p = string1.indexOf("value=", p);
    Serial.println(string1.substring(p + 7, p + 15));
    wert = string1.substring(p + 7, p + 15).toDouble();
    Serial.println(wert,6);
  } else {
    Serial.println("Fehler: kein Wert gefunden!");
  }
}

void loop() {}

Bei variableren Antworten lohnt eine Funktion mit einem mehr oder minder komplexen Parser.

StefanL38:
hunderte Dateien und NULL Beispiel wie man es benutzt. ...

Nicht nur unqualifiziert rumschreien, sondern einfach lesen lernen.

Es gibt dort einen sehr umfangreichen Ordner "docs".

Gruß Tommy

Tommy56:
Es gibt dort einen sehr umfangreichen Ordner "docs".

Ja, das sind aber hunderte Dateien :wink:

Du hast natürlich recht,

Nicht nur unqualifiziert rumschreien, sondern einfach lesen lernen.

aber das ist vergebens.

Denn schon in der Beschreibung dritte Zeile (und zum anklicken!)
The online HTML version of these docs: http://leethomason.github.io/tinyxml2/ (link inside ist httpS verknüpft)

Und wer bis dahin nicht liest, will es auch nicht.

Das Beispiel hier das da aufgeführt wird fand ich oersönlich nicht hilfreich.

/* ------ Example 2: Lookup information. ---- */
{
    XMLDocument doc;
    doc.LoadFile( "dream.xml" );

    // Structure of the XML file:
    // - Element "PLAY"      the root Element, which is the
    //                       FirstChildElement of the Document
    // - - Element "TITLE"   child of the root PLAY Element
    // - - - Text            child of the TITLE Element

    // Navigate to the title, using the convenience function,
    // with a dangerous lack of error checking.
    const char* title = doc.FirstChildElement( "PLAY" )->FirstChildElement( "TITLE" )->GetText();
    printf( "Name of play (1): %s\n", title );

    // Text is just another Node to TinyXML-2. The more
    // general way to get to the XMLText:
    XMLText* textNode = doc.FirstChildElement( "PLAY" )->FirstChildElement( "TITLE" )->FirstChild()->ToText();
    title = textNode->Value();
    printf( "Name of play (2): %s\n", title );
}

ich bin kein ganz blutiger Anfänger mehr. Mir persönlich ist es mit diesem Beispiel nicht gelungen das allgemein zugrunde liegende Muster zu erkennen.

StefanL38:
Das finde ich zum kotzen.

Und wir Deine Entgleisungen.

Mache es doch einfach besser, anstelle nur rumzumotzen.

Gruß Tommy

StefanL38:
Ist ein Beispiel das bestefalls für XML-Parser-Experten geeignet ist die sich nicht mehr genau an ein Detail der Syntax erinnern können. Aber auf keinen Fall um Anfängern zu zeigen wie es geht.

Nun ja es ist kostenlos und deswegen meckern die anderen wohl nicht. Man muss ja froh sein das jemand den Code an sich online gestellt hat.

Ich habe schon so und so oft auf GitHub erlebt

  • das es noch nicht einmal einen Doc-Ordner gibt.

  • das der Beispielcode Compiler-Fehlermeldungen produziert

  • die Beispiele so dermaßen kyrptisch sind das man doch nichts mit ihnen anfangen kann

  • jetzt kommt noch hinzu das die Leute die Hinweise auf weitere Dokumentation einfach irgendwo in ihrer GitHub-section einstreuen. Das finde ich zum kotzen.

Aber gut. Ich belasse es Zukunft bei einer akustisch-verbalen Schimpfkanonade und verweigere das Feedback

Das Beispiel ist gut. Das die anderen nicht meckern, weil es kostenlos ist, halte ich für eine gewagte These. Es gibt keinerlei Hinweise dazu. Aus den mehr als 1K commits ist das auch nicht ersichtlich.

Was Du auf GitHub erlebt hast, transformierst Du mit einer absurden Abneigung des Lesens auf alles Neue?
Eigenartige Denkweise.

Und nochmal: Da ist nichts irgendwo reingestreut, sondern sehr strukturiert und übersichtlich erläutert.
Mich aber dann so anzu***** und das nicht mal trotz Hinweis zu ändern; kann man machen.

Ist nur nicht das erste Mal. Achte drauf, das es nicht zum Dauerzustand wird.

Hallo my_xy_projekt,

interessante Antwort. Aha -- hm -- . Jetzt würde ich gerne ernsthaft dazulernen. Wirklich ernsthaft.
Ich wollte nun wirklich nicht jemanden persönlich an(zu)*****

Welchen Textabschnitt interpretierst du als "an(zu)***** " ? ? Da bin ich wohl blind auf beiden Augen und habe Asperger-Syndrom

@Tommy:

Ich bin dabei einen entsprechenden Parser speziell für das vom TO geposteten XML-String zu erstellen.
Siehe code unten. Das ist ein frühes Alpha-Stadium compiliert und spuckt den gesuchten Teilstring "3.00000" aus.

Die Qualität dieses Codes genügt noch lange nicht meinen persönlichen Ansprüchen die er erfüllen muss wenn ich ihn
auf GitHub hochlade. Und ich würde ihn auch ganz bestimmt nicht XML-parser nennen. Das würde viel zu hohe Ewartungen wecken die der code nicht erfüllt.

Der Code ist weder aufgeräumt noch auf Übersichtlichkeit getrimmt. Man muss ausserdem noch sehr gründlich prüfen welche Variablität die empfangen XML-Strings (die der TO bei seiner Abfragen empfängt) haben können und ob mein code mit dieser Variabilität richtig umgehen kann.

Schon klar wenn man versteht wie man TinyXML benutzt dann kann TinyXML alle XML-Daten die der Spezifikation entsprechen parsen und das passende zurückliefern.

#include <PString.h>
char    XML_Str_AoC[1024] = " "; 
PString XML_Str_PS(XML_Str_AoC, sizeof(XML_Str_AoC));

char    XML_SubStr_AoC[1024] = " ";
PString XML_SubStr_PS(XML_SubStr_AoC, sizeof(XML_SubStr_AoC));

char    Value_AoC[64] = " ";
PString Value_PS(Value_AoC, sizeof(Value_AoC));

char    IDStr_AoC[64] = "=";
PString IDStr_PS(IDStr_AoC, sizeof(IDStr_AoC));

char    Separator_AoC[64] = "=";
PString Separator_PS(Separator_AoC, sizeof(Separator_AoC));

unsigned long IDPos;
unsigned long ValuePos;
unsigned long EndOfValuePos;
unsigned long StrLen;

unsigned long BeginOfSubStr (char* p_PointerToSource, char* p_PointerToSubStr) {
  unsigned long result = strstr(p_PointerToSource,p_PointerToSubStr) - p_PointerToSource;
  return result;
}

unsigned long EndOfSubStr (char* p_PointerToSource, char* p_PointerToSubStr) {
  unsigned long result = strstr(p_PointerToSource,p_PointerToSubStr) - p_PointerToSource + strlen(p_PointerToSubStr);
  return result;
}

// my personal naming-convention parameter of functions start with prefix "p_"
void ExtractUntilSeparator(char* p_PointerToTarget, char* p_PointerToSeparator, char* p_PointerToSource)
{
  Serial.println("entering ExtractUntilSeparator");
  unsigned int LengthUntilDelimiter = strstr(p_PointerToSource,p_PointerToSeparator) - p_PointerToSource + 1;

  strlcpy(p_PointerToTarget,p_PointerToSource,LengthUntilDelimiter);

  Serial.print("p_PointerToSource:>#");
  Serial.print(p_PointerToSource);
  Serial.println("#");

  Serial.print("p_PointerToTarget:>#");
  Serial.print(p_PointerToTarget);
  Serial.println("#");
  
  Serial.print("p_PointerToSeparator:>#");
  Serial.print(p_PointerToSeparator);
  Serial.println("#");
  
  Serial.println("leaving ExtractUntilSeparator");
}

// my personal naming-convention parameter of functions start with "p_"
void ExtractValueBehindSeparator(char* p_PointerToTarget, char* p_PointerToSeparator, char* p_PointerToSource)
{
  Serial.println("entering ExtractValueBehindSeparator");
  unsigned int PosOfSeparatorEnd = strstr(p_PointerToSource,p_PointerToSeparator) - p_PointerToSource + strlen(p_PointerToSeparator);
  // if separatorstring was  found   
  if (PosOfSeparatorEnd < strlen(p_PointerToSource) )
  {
    Serial.print("PosOfSeparatorEnd:>#");
    Serial.print(PosOfSeparatorEnd);
    Serial.println("#");
    unsigned int NoOfBytesUntilEoString = strlen (p_PointerToSource) - PosOfSeparatorEnd + 1; 
    
    strlcpy(p_PointerToTarget, p_PointerToSource + PosOfSeparatorEnd, NoOfBytesUntilEoString);
  }
  else 
  { 
    p_PointerToTarget = ""; // if no separator was found there is nothing behind the separator
  }

  Serial.print("p_PointerToSource:>#");
  Serial.print(p_PointerToSource);
  Serial.println("#");

  Serial.print("p_PointerToTarget:>#");
  Serial.print(p_PointerToTarget);
  Serial.println("#");
  
  Serial.print("p_PointerToSeparator:>#");
  Serial.print(p_PointerToSeparator);
  Serial.println("#");
  
  Serial.println("leaving ExtractValueBehindSeparator");
}

void setup() 
{
  Serial.begin(115200);
  Serial.println();
  Serial.println("setup-Start");

  XML_Str_PS += "HTTP/1.0 200 OK ";
  XML_Str_PS += "Content-Type: text/xml ";
  XML_Str_PS += "Access-Control-Allow-Origin: * ";
  XML_Str_PS += "X-Frame-Options: SAMEORIGIN ";
  XML_Str_PS += "X-Content-Type-Options: nosniff ";
  XML_Str_PS += "X-XSS-Protection: 1; mode=block ";
  XML_Str_PS += "X-Robots-Tag: none ";
  XML_Str_PS += "X-Download-Options: noopen ";
  XML_Str_PS += "X-Permitted-Cross-Domain-Policies: none ";
  XML_Str_PS += "Referrer-Policy: no-referrer ";
  XML_Str_PS += "Content-Length: 300 ";
  XML_Str_PS += "Connection: close ";
  XML_Str_PS += "Date: Fri, 19 Jun 2020 20:20:38 GMT ";
  XML_Str_PS += "<?xml version='1.0' encoding='ISO-8859-1' ?><systemVariables><systemVariable name='Grube Stand' variable='3.000000' value='3.000000' value_list='' value_text='' ise_id='2632' min='0' max='65000' unit='cm' type='4' subtype='0' timestamp='1592598038' value_name_0='' value_name_1=''/></systemVariables>"; 

  Serial.print("XML_Str_PS#");
  Serial.print(XML_Str_PS);
  Serial.print("#");
  Serial.println();

  IDStr_PS = "'Grube Stand'";

  Serial.print("1: IDStr_PS#");
  Serial.print(IDStr_PS);
  Serial.print("#");
  Serial.println();

  IDPos = BeginOfSubStr(XML_Str_PS,IDStr_PS);
  Serial.print("IDPos:");
  Serial.print(IDPos);
  Serial.print("#");
  Serial.println();
  
  IDStr_PS = "value_list=";

  Serial.print("2:IDStr_PS#");
  Serial.print(IDStr_PS);
  Serial.print("#");
  Serial.println();
  
  ValuePos = BeginOfSubStr(XML_Str_AoC,IDStr_AoC);

  Serial.print("XML_Str_PS#");
  Serial.print(XML_Str_PS);
  Serial.print("#");
  Serial.println();

  Serial.print("ValuePos:");
  Serial.print(ValuePos);
  Serial.print("#");
  Serial.println();

  StrLen = ValuePos - IDPos; 
  Serial.print("StrLen:");
  Serial.print(StrLen);
  Serial.print("#");
  Serial.println();

//Grube Stand' variable='3.000000' value='3.000000'   
  strncpy(XML_SubStr_PS,  XML_Str_PS + IDPos, StrLen);

  Serial.print("SubStr#");
  Serial.print(XML_SubStr_PS);
  Serial.print("#");
  Serial.println();

  XML_Str_PS = XML_SubStr_PS;
  Separator_PS = "value='";

  IDPos = EndOfSubStr(XML_SubStr_PS,Separator_PS);

  Serial.print("3: IDPos:");
  Serial.print(IDPos);
  Serial.print("#");
  Serial.println();

  StrLen = strlen(XML_Str_PS) - IDPos + 1;

  Serial.print("StrLen:");
  Serial.print(StrLen);
  Serial.print("#");
  Serial.println();

  strncpy(XML_SubStr_PS,  XML_Str_PS + IDPos, StrLen);

  Serial.print("SubStr#");
  Serial.print(XML_SubStr_PS);
  Serial.print("#");
  Serial.println();

  XML_Str_PS = XML_SubStr_PS;
  Separator_PS = "'";

  ExtractUntilSeparator(XML_SubStr_PS, Separator_PS, XML_Str_PS);
  Serial.print("value SubStr#");
  Serial.print(XML_SubStr_PS);
  Serial.print("#");
  Serial.println();

}

void loop() {
}

ursprüngich hattee ich ziemlich viele Kommentare drin. ABer dann komme ich über das Limit von 9000 Zeichen.
Deshalb die Code-Version mit Kommentaren im Anhang.

viele Grüße Stefan

PString-XML-Parser-002-Test.zip (2.08 KB)

StefanL38:
Jetzt würde ich gerne ernsthaft dazulernen. Wirklich ernsthaft.

Ganz einfach, bitte vermeide Ausdrücke aus der Fäkaliensprache. Ohne jede inhaltlichen Bewertung beispielsweise so:

"hunderte Dateien und NULL Beispiel wie man es benutzt. DAS IST DOCH BLÖD!!"

Das wäre zwar meiner Meinung nach ebenfalls noch übertrieben, aber innerhalb meines Toleranzbereichs.

Wenn Du Deinen Text in #3 entsprechend änderst, könnten wir von mir aus wieder zum sachlichen Teil zurückkehren, was mich freuen würde.

schnigge5:
Kann mir vielleicht jemand veraten wie ich diese 3.000000 nun in eine float-Variable bekomme, sodass ich damit rechnen kann?

Für einen Esp, eventuell so?

String incomingStr = R"(HTTP/1.0 200 OK
Content-Type: text/xml
Access-Control-Allow-Origin: *
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Robots-Tag: none
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Referrer-Policy: no-referrer
Content-Length: 300
Connection: close
Date: Fri, 19 Jun 2020 20:20:38 GMT
<?xml version="1.0" encoding="ISO-8859-1" ?><systemVariables><systemVariable name='Grube Stand' variable='3.000000' value='3.000000' value_list='' value_text='' ise_id='2632' min='0' max='65000' unit='cm' type='4' subtype='0' timestamp='1592598038' value_name_0='' value_name_1=''/></systemVariables>)";

float xmlTakeParam(String &inStr, const String &needParam) {
  int CountChar = needParam.length();
  return inStr.substring(inStr.lastIndexOf(needParam) + CountChar + 1, inStr.indexOf(needParam) + CountChar + 9).toFloat();
}

void setup() {
  Serial.begin(115200);
}

void loop() {
  for (float systemVariable = xmlTakeParam(incomingStr, "value=");; Serial.printf("\nSystemvariable als float: %f\n", systemVariable), delay(2e3));
}

Gruß Fips

Hallo Fips,

wie stellst du jetzt sicher das die wiederholte Verwendung der String-variable nicht zu Speicherüberlauf und Programm-Crash führt?

viele Grüße Stefan

StefanL38:
Hallo Fips,

wie stellst du jetzt sicher das die wiederholte Verwendung der String-variable nicht zu Speicherüberlauf und Programm-Crash führt?

viele Grüße Stefan

Wo, wird die wiederholt verwendet?

Gruß Fips

StefanL38:
also ich habe in den doc-ordner reingeschaut. Da gibt es sehr viele XML-Dateien aber leider keinen Beispielcode wie man die TinyXML anwendet. Also gaanz simple Beispiele die exemplarisch zeigen wie man ein bestimmtes Detail in den Gesamtdaten ehrauspickt.

Du hast etwas wichtiges übersehen. Die Doku wurde unter Zuhilfenahme von doxygen erstellt. Dabei rausgekommen ein html-basiertes Recherchesystem. Steht aber auch in der Einführung :wink:

Variante 1: Den doc-Ordner lokal abspeichern und dort die Datei index.html aufrufen
Variante 2: Die Onlineversion nutzen - Steht in der Einführung in der 3ten Zeile klickbar.

StefanL38:
ich bin kein ganz blutiger Anfänger mehr. Mir persönlich ist es mit diesem Beispiel nicht gelungen das allgemein zugrunde liegende Muster zu erkennen.

Wenn Du die Doku öffnest, findest Du unter "Related Pages" "Get information out of XML" eine ausführliche Erklärung zu genau diesem Beispielcode.

Im Übrigen find ich die Doku zu den Klassen sehr umfangreich. So habe ich ganz selten eine Refernz einsehen können...

Also ich war jetzt auf dieser Seite hier TinyXML-2: Related Pages

Da gibt es einige Links die alle

404
File not found
The site configured at this address does not contain the requested file.
If this is your site, make sure that the filename case matches the URL.
For root URLs (like

produzieren.
Auf github war ich hier: tinyxml2/docs at master · leethomason/tinyxml2 · GitHub
jede Menge html-files. Da gibt es ein File
tinyxml2/index.html at master · leethomason/tinyxml2 · GitHub
Wenn ich das anklicke sehe ich den Sourcecode des Indexfiles
Ich habe wahrscheinlich zu lange in die superhellen LEDs reingeschaut und deswegen sehe ich es nicht
Wärst du so nett und würdest den direkten Link posten der die Erläuterung zum Beispiel direkt anzeigt?
Was natürlich ultraspitzenklasse wäre - wenn es denn in 10 Minuten runtergeschrieben ist
ein kleines Demoprogrämmchen das die TinyXML-library benutzt um den vom TO genannten Wert auszulesen.
viele Grüße Stefan

Merkst Du nicht, dass das nur noch peinlich ist, was Du bringst?

Gruß Tommy