xml — n_pbt_xml #
← Komponentenreferenz · Inhalt des Handbuchs
XML Element für Element schreiben — Öffnen, Attribute, Text, Schließen — mit dem Escaping für Sie erledigt, dann eines zurücklesen mit echtem XPath:
of_load,of_get_value,of_get_attr,of_count. PowerBuilder 10 hat keinen XML-Parser; dieser nutzt DOMParser und document.evaluate der WebView2-Engine, synchron aufgerufen.
▶ Live ansehen — Demoanwendung, Kachel XML: die Ergebnisse, der zugehörige Code und diese Seite nebeneinander.
Kurzüberblick #
Die Bau-Seite ist reines PowerScript (einen String zu bauen braucht keine Engine). Die Lese-Seite öffnet bei der ersten Abfrage eine verborgene Seite. Das XPath ist Version 1.0, wie der Browser es auswertet. Es gibt ein Dokument auf einmal: ein Lesen auf einem gebauten Dokument lädt es zuerst in die Seite, es wird das geladene Dokument, und das nächste of_start_element beginnt ein neues. Ein Lesen wird abgelehnt, solange ein Element des gebauten Dokuments noch offen ist (-4, leer oder false, und is_last_error): schließen Sie zuerst Ihre Elemente — nichts geht verloren. of_xml und of_pretty, die auf einer Kopie arbeiten, bleiben verfügbar.
Schnellstart #
// Local variables
n_pbt_xml lnv_xml
// Create the object once, free it when done
lnv_xml = create n_pbt_xml
// Read : load, then query with XPath
lnv_xml.of_load(/*xml*/ '<order id="4152"><customer>Ada</customer></order>')
IF lnv_xml.of_is_valid() THEN
MessageBox("Customer", lnv_xml.of_get_value(/*xpath*/ "/order/customer")) // Ada
MessageBox("Id", lnv_xml.of_get_attr(/*xpath*/ "/order", /*name*/ "id")) // 4152
END IF
// Build : element by element, escaping done for you
lnv_xml.of_clear()
lnv_xml.of_start_element(/*name*/ "order")
lnv_xml.of_element_attr(/*name*/ "id", /*value*/ "4152")
lnv_xml.of_leaf(/*name*/ "customer", /*text*/ "Ada & Co")
lnv_xml.of_end_element()
// lnv_xml.of_xml() -><order id="4152"><customer>Ada & Co</customer></order>
// Free the object
destroy lnv_xml
Eigenschaften #
| Eigenschaft | Typ | Standard | Rolle |
|---|---|---|---|
is_last_error | string | "" | Warum das letzte Lesen leer, false, 0 oder einen negativen Code lieferte: fehlerhaftes Dokument, von der Engine abgelehnter XPath, XPath ohne Treffer, nichts geladen, Demo-Grenze, Seite ohne Antwort. Leer nach einem erfolgreichen Lesen. Auch der Builder schreibt hierher, wenn er einen ungültigen Element- oder Attributnamen ablehnt |
ipo_owner | powerobject | null | Das visuelle Objekt, für das dieses Hilfsobjekt arbeitet: die Lizenz wird an seiner Klasse geprüft. Vor dem ersten Lesen setzen; später gesetzt, wird es beim nächsten Lesen übergeben. Nur in der Demoanwendung nötig; ein Entwicklungs- oder Laufzeitschlüssel schaltet das Lesen ohne es frei. Nicht freigeschaltet läuft das Lesen im Demomodus — Dokumente mit höchstens 64 KB, Änderungen inbegriffen. Das Bauen braucht es nicht: es ist reines PowerScript |
Ein Dokument bauen #
| Element | Rolle |
|---|---|
of_start_element (string as_name) | Öffnet ein Element (Elemente verschachteln sich: ein offenes Tag wird zuerst geschlossen). Ein ungültiger Name (leer, mit Leerzeichen, verbotenes Zeichen, mehr als ein :, ein : am Anfang oder Ende) wird abgelehnt: is_last_error sagt warum, und das Element bleibt mit seinem ganzen Inhalt außerhalb des Dokuments |
of_element_attr (string as_name, string as_value) | Fügt dem offenen Element ein Attribut hinzu, Wert escaped — Zeilenumbrüche und Tabulatoren eingeschlossen, damit sie unverändert zurückgelesen werden (vor jedem Kind oder Text). Ein ungültiger Name wird abgelehnt (is_last_error); derselbe Name zweimal ergibt EIN Attribut, mit dem zweiten Wert |
of_element_text (string as_text) | Der Textinhalt des aktuellen Elements, escaped; die Steuerzeichen, die XML verbietet, werden entfernt (ein einziges machte das ganze Dokument fehlerhaft) |
of_end_element ( ) | Schließt das aktuelle Element (leer, selbstschließend <name/>) |
of_leaf (string as_name, string as_text) | Ein Blatt-Element in einem Aufruf — <name>Text</name>, escaped |
of_clear ( ) → long | Leert das Dokument — gebaut oder geladen — um ein anderes zu beginnen; ein geladenes Dokument verlässt auch die Seite. Liefert 0 |
of_xml ( ) → string | Das Dokument wie es ist: das, was Sie gebaut oder geladen (of_load) haben, nach jeder Änderung — die einzige Ausgabe, zum Senden, Speichern oder Zurückschreiben. Ein gebautes Dokument braucht keine Seite (offene Elemente werden geschlossen) ; ein geladenes wird von der Engine serialisiert. of_pretty ist die eingerückte Form |
Ein Dokument lesen (XPath) #
| Element | Rolle |
|---|---|
of_load (string as_xml) → long | Lädt einen XML-Text (vom DOMParser der Engine analysiert). Liefert 0 wenn wohlgeformt, -5 wenn leer, -4 bei ungültigem XML (oder, im Demomodus, zu lang nach Auflösung seiner Entitäten), -2 wenn die verborgene Seite nicht antwortete. Bei negativem Code bleibt NICHTS: weder ein zuvor geladenes noch ein halb gebautes Dokument |
of_is_valid ( ) → boolean | Wahr, wenn ein wohlgeformtes Dokument vorliegt — mit of_load geladen oder gebaut (es wird dann in die Seite geladen, wie bei jedem Lesen). Falsch, wenn nichts da ist oder das gebaute Dokument fehlerhaft ist oder noch ein offenes Element hat |
of_exists (string as_xpath) → boolean | Wahr, wenn der XPath mindestens einen Knoten trifft. Ein Ausdruck, der einen WERT liefert (count(//line)), ist kein Knoten: lesen Sie ihn mit of_get_value |
of_get_value (string as_xpath) → string | Der Textinhalt des ERSTEN passenden Knotens. Leer, wenn keiner (is_last_error sagt es). Ein XPath, der einen WERT liefert, gibt ihn als Text: count(//line) → 3, sum(//@qty), boolean(//paid) → true |
of_get_attr (string as_xpath, string as_name) → string | Der Wert des Attributs as_name am ersten passenden Knoten. Leer, wenn abwesend |
of_count (string as_xpath) → long | Wie viele Knoten der XPath auswählt. 0 wenn keiner (eine XPath-Zählung ist nie negativ); is_last_error sagt, wann der XPath selbst abgelehnt wurde |
of_name (string as_xpath) → string | Der Tag-Name des ersten passenden Knotens. Leer, wenn keiner |
of_pretty ( ) → string | Das Dokument, wie es ist — gebaut oder geladen, was of_xml liefert — zum Lesen neu eingerückt. Nichts geht verloren: CDATA, Kommentare, Verarbeitungsanweisungen und die XML-Deklaration bleiben, und ein Element mit Text wird unverändert auf einer Zeile geschrieben. Leer, wenn nichts da ist oder ein gebautes Dokument nicht wohlgeformt ist |
Mehrere Knoten und das Dokument #
| Element | Rolle |
|---|---|
of_get_values (string as_xpath, ref string as_values[]) → long | Der Textinhalt JEDES passenden Knotens, in as_values; liefert die Anzahl. Wo of_get_value nur den ersten liefert |
of_get_attrs (string as_xpath, string as_name, ref string as_values[]) → long | Der Wert des Attributs as_name an JEDEM passenden Knoten (die id jeder Zeile); liefert die Anzahl |
of_get_attr_names (string as_xpath, ref string as_names[]) → long | Die Namen aller Attribute des ersten passenden Knotens (Aufzählung); liefert die Anzahl |
Ein Dokument ändern #
Die Schreib-Seite ändert den geladenen Baum an Ort und Stelle; of_xml liefert das Ergebnis. Jede zielt auf den ERSTEN passenden Knoten (außer of_remove, das alle nimmt), liefert 0 bei Erfolg, -4 wenn nichts passte oder die Änderung abgelehnt wurde (is_last_error sagt warum), -5 bei leerem Argument, -2 wenn die Seite nicht antwortete.
| Element | Rolle |
|---|---|
of_set_value (string as_xpath, string as_text) → long | Setzt den Text des ersten passenden Knotens (seine Kinder werden ersetzt) |
of_set_attr (string as_xpath, string as_name, string as_value) → long | Setzt (oder fügt) ein Attribut am ersten passenden Knoten. Ein präfigierter Name (xsi:type) kommt in den Namensraum, den sein Präfix an diesem Knoten hat (oder mit of_register_namespace gebunden); ein nirgends gebundenes Präfix wird abgelehnt (-4, is_last_error) |
of_remove_attr (string as_xpath, string as_name) → long | Entfernt ein Attribut vom ersten passenden Knoten |
of_add_child (string as_xpath, string as_tag, string as_text) → long | Fügt ein Kindelement <as_tag>as_text</as_tag> unter dem ersten passenden Knoten an (das Kind erbt Namensraum und Präfix des Elternteils; ein präfigiertes Tag p:item nimmt den Namensraum seines Präfixes, oder -4, wenn es nirgends gebunden ist). -4 auch, wenn der Knoten keine Kinder haben kann (ein Attribut, ein Text) oder das Tag kein gültiger Name ist |
of_add_xml (string as_xpath, string as_fragment) → long | Pfropft ein bereits geformtes XML-Fragment (ein oder mehrere Geschwisterelemente) unter den ersten passenden Knoten — was of_add_child nicht kann, da es nur ein Tag und Text nimmt. Das Fragment muss wohlgeformt sein; es erbt die an seinem Ziel geltenden Namensräume, wie of_add_child (<line> unter <order xmlns='urn:acme'> liegt in urn:acme, <s:Item/> unter einem SOAP-s:Body deklariert nichts) |
of_remove (string as_xpath) → long | Entfernt ALLE passenden Knoten (eine Zeile, einen veralteten Zweig, ein Attribut). Liefert, wie viele wirklich entfernt wurden (>= 0; bei 0 sagt is_last_error warum), -4 wenn nichts geladen ist, -5 bei leerem XPath, -2 wenn die Seite nicht antwortete. Das Wurzelelement bleibt: of_clear leert ein Dokument |
Namensräume #
Ein präfigierter XPath (SOAP, eine Unternehmens-API) löst ein Präfix, das das Dokument deklariert (xmlns:s="…", auf beliebigem Element), selbst auf. ⚠️ Die häufigste Falle: der STANDARD-Namensraum. <order xmlns="urn:acme"><customer>… hat kein Präfix, und doch trifft /order/customer NICHTS: XPath 1.0 kennt keinen Standard-Namensraum. Binden Sie ein Präfix Ihrer Wahl mit of_register_namespace("a", "urn:acme") und schreiben Sie /a:order/a:customer. of_clear_namespaces vergisst die Bindungen. Es gibt kein XSLT: Chromium entfernt es aus der Engine (transformieren Sie serverseitig oder in PowerScript). Eine Schemavalidierung per XSD gibt es nicht: die Engine hat keine.
| Element | Rolle |
|---|---|
of_register_namespace (string as_prefix, string as_uri) → long | Bindet ein Präfix an die URI seines Namensraums, damit ein präfigierter XPath aufgelöst wird. Liefert 0, -5 bei leerem Präfix oder leerer URI, -2 wenn die Seite nicht antwortete. Die Bindungen gelten bis of_clear_namespaces oder of_reset |
of_clear_namespaces ( ) → long | Vergisst alle registrierten Präfixe: ein Präfix, das das Dokument nicht deklariert, trifft nichts mehr, bis es wieder gebunden ist. Liefert 0, -2 wenn die Seite nicht antwortete |
// A SOAP response : the prefix declared by the document resolves on its own
lnv_xml.of_load(/*xml*/ ls_soap)
ls_ok = lnv_xml.of_get_value(/*xpath*/ "//s:Body/result/status")
// A DEFAULT namespace (xmlns="urn:acme") : bind a prefix of your choice
lnv_xml.of_load(/*xml*/ '<order xmlns="urn:acme"><customer>Ada</customer></order>')
lnv_xml.of_register_namespace(/*prefix*/ "a", /*uri*/ "urn:acme")
ls_name = lnv_xml.of_get_value(/*xpath*/ "/a:order/a:customer") // Ada
// Mutate, then read the result back
lnv_xml.of_set_value(/*xpath*/ "/a:order/a:customer", /*text*/ "Grace")
lnv_xml.of_add_child(/*xpath*/ "/a:order", /*tag*/ "total", /*text*/ "690.50")
// Graft a whole fragment at once (of_add_child adds only one tag)
lnv_xml.of_add_xml(/*xpath*/ "/a:order", /*fragment*/ '<lines xmlns="urn:acme"><line sku="1">A</line><line sku="2">B</line></lines>')
ls_out = lnv_xml.of_xml()
Die verborgene Seite #
| Element | Rolle |
|---|---|
of_open ( ) → long | Erzeugt die verborgene Seite (Leseseite). Optional — das erste Lesen tut es. Liefert das Handle (> 0) oder -2, wenn sie nicht erzeugt werden konnte (is_last_error sagt, warum) |
of_is_open ( ) → boolean | Wahr, sobald die verborgene Seite existiert |
of_close ( ) | Gibt die verborgene Seite frei. Das Bauen läuft ohne sie weiter, und ein geladenes Dokument geht nicht verloren: es wird als Text behalten, und das nächste Lesen lädt es wieder. Wird beim Zerstören für Sie erledigt |
of_reset ( ) | Zurück zu den Standardwerten: der Builder geleert, der Lesezustand gelöscht |
Umfang. XML wird über die Engine gelesen (DOMParser, XPath):
n_pbt_xmlöffnet beim ersten Lesen eine verborgene Seite, anders als json, das in reinem PowerScript parst. Um ein XML als aufklappbaren Baum zu zeigen, siehe xmltree.