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, und Zahlen und Datumswerte, die auf jedem Rechner gleich gelesen werden (of_get_decimal,of_get_date). PowerBuilder hat PBDOM (ein DOM ohne XPath, eine zu verteilende PBNI-Erweiterung) undXMLParseString; dieses hier liefert XPath 1.0 und Namensräume, ohne etwas zu verteilen, und 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 of_get_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 |
|---|---|---|---|
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 65 536 Zeichen, Änderungen inbegriffen; of_is_valid ist falsch und of_pretty leer für ein längeres gebautes Dokument. Das Bauen braucht es nicht: es ist reines PowerScript |
Ein Dokument bauen #
| Element | Rolle |
|---|---|
of_get_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 |
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: of_get_last_error() sagt warum, und das Element bleibt mit seinem ganzen Inhalt außerhalb des Dokuments; ebenso ein zweites Element auf oberster Ebene, sobald die Wurzel geschlossen ist: ein Dokument hat nur eine Wurzel |
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 (of_get_last_error()); derselbe Name zweimal ergibt EIN Attribut, mit dem zweiten Wert. Nach einem Kind oder Text oder ohne offenes Element angegeben, wird es weggelassen und of_get_last_error() sagt es. Überladungen: decimal, date, datetime, boolean, geschrieben wie bei of_leaf |
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). Ohne offenes Element wird der Text weggelassen, und of_get_last_error() sagt es |
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. Überladungen: ein decimal, ein date, ein datetime oder ein boolean, geschrieben wie XML Schema sie schreibt, unabhängig vom Rechner — 690.5 (ein Punkt), 2026-10-31, 2026-10-31T14:30:00, true; ein NULL schreibt ein leeres Element |
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. Jeder Aufruf der Seite wartet höchstens 5 Sekunden: ein Dokument von mehreren zehn MB, vor allem in einer 32-Bit-Anwendung, kann -2 liefern |
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 — und im Demomodus für ein gebautes Dokument mit mehr als 65 536 Zeichen |
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 (of_get_last_error() sagt es). Ein XPath, der einen WERT liefert, gibt ihn als Text: count(//line) → 3, sum(//@qty), boolean(//paid) → true. / liefert den Text des ganzen Dokuments; ein Ausdruck, der keine Zahl ist (ein sum() über einen Text), liefert leer mit seinem Grund, nie NaN. Eine Zahl, ein Datum, ein Boolean werden mit of_get_number, of_get_decimal, of_get_date… auf jedem Rechner gleich gelesen |
of_get_attr (string as_xpath, string as_name) → string | Der Wert des Attributs as_name am ersten passenden Knoten. Leer, wenn der Knoten oder das Attribut fehlt — of_get_last_error() sagt dann „no node matched“ oder „no such attribute“; ein leer geschriebenes Attribut (a="") liefert leer ohne Grund. Ein leerer Name wird ebenso abgelehnt |
of_count (string as_xpath) → long | Wie viele Knoten der XPath auswählt. 0 wenn keiner; -4 wenn nichts geladen ist, ein Element des gebauten Dokuments noch offen ist oder die Engine den XPath abgelehnt hat, -2 wenn die Seite nicht antwortete; of_get_last_error() sagt welches |
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. CDATA, Kommentare, Verarbeitungsanweisungen und die XML-Deklaration bleiben, und ein Element mit Text wird unverändert auf einer Zeile geschrieben; neu eingerückt wird der Leerraum ZWISCHEN Elementen — außer in einem mit xml:space="preserve" markierten Element, das unverändert geschrieben wird. Leer, wenn nichts da ist, wenn ein gebautes Dokument nicht wohlgeformt ist, und im Demomodus für ein Dokument mit mehr als 65 536 Zeichen |
Zahlen, Datumswerte und Booleans #
XML Schema schreibt eine Zahl mit einem Punkt und ein Datum in ISO 8601, unabhängig vom Land. Dec("690.50") oder Date("2026-10-31") hängen dagegen von den Regionaleinstellungen des Rechners ab. Diese Leser prüfen den Wert gegen seinen Typ und liefern ihn auf jedem Rechner gleich; ein fehlender, leerer oder andersartiger Wert liefert NULL, und of_get_last_error() sagt warum. Ein XPath, der einen Wert liefert (sum(//qty)), funktioniert auch. Zum Schreiben: of_leaf, of_element_attr und of_set_value nehmen ein decimal, date, datetime oder boolean.
| Element | Rolle |
|---|---|
of_get_number (string as_xpath) → double | Die Zahl als double: 690.50, -1.5E3, +.5; Leerraum ringsum ignoriert; 12 kg, 1,5, INF werden abgelehnt |
of_get_decimal (string as_xpath) → decimal | Die Zahl als decimal, jede Ziffer erhalten (ein Betrag verliert nie seine Cents); abgelehnt über die 28 Stellen eines decimal hinaus |
of_get_longlong (string as_xpath) → longlong | Die Ganzzahl als longlong, jede Ziffer erhalten (auch eine ID über 2^53); 2.5 wird abgelehnt, nicht abgeschnitten |
of_get_boolean (string as_xpath) → boolean | true oder 1 → true, false oder 0 → false; alles andere (yes, Y) liefert NULL |
of_get_date (string as_xpath) → date | 2026-10-31 oder das Datum eines Zeitstempels; eine Zeitzone (Z, +02:00) wird angenommen, aber nicht angewendet. Abgelehnt: ein Tag, den es nicht gibt (2026-02-30), ein Jahr außerhalb von 1000 bis 3000 |
of_get_datetime (string as_xpath) → datetime | 2026-10-10T14:30:00, mit oder ohne Sekundenbruchteil, 2026-10-10 14:30 oder ein Datum allein (Mitternacht); die Uhrzeit ist die GESCHRIEBENE: eine Zeitzone wird nicht angewendet, wie n_pbt_json sie liest |
// Local variables
n_pbt_xml lnv_xml
decimal ldc_total
date ld_due
// Create the object once, free it when done
lnv_xml = create n_pbt_xml
// Write : a point and ISO 8601, whatever the regional settings
lnv_xml.of_start_element(/*name*/ "invoice")
lnv_xml.of_element_attr(/*name*/ "paid", /*value*/ false)
lnv_xml.of_leaf(/*name*/ "total", /*value*/ 690.50)
lnv_xml.of_leaf(/*name*/ "due", /*value*/ Date(2026, 10, 31))
lnv_xml.of_end_element()
// lnv_xml.of_xml() -> <invoice paid="false"><total>690.5</total><due>2026-10-31</due></invoice>
// Read them back as values you can compute with
ldc_total = lnv_xml.of_get_decimal(/*xpath*/ "/invoice/total")
ld_due = lnv_xml.of_get_date(/*xpath*/ "/invoice/due")
// A value that is not of its type is NULL : is_last_error says why
IF IsNull(ldc_total) THEN MessageBox("Total", lnv_xml.of_get_last_error())
// Free the object
destroy lnv_xml
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, 0 wenn keiner, -4 wenn nichts geladen ist oder der XPath abgelehnt wurde, -2 wenn die Seite nicht antwortete. 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), leer für einen Knoten ohne es; liefert die Anzahl, 0 wenn keiner, -5 bei leerem Namen, -4 wenn nichts geladen ist oder der XPath abgelehnt wurde, -2 wenn die Seite nicht antwortete |
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, 0 wenn der Knoten keine hat oder kein Knoten passt (of_get_last_error() sagt es), -4 wenn nichts geladen ist, der XPath abgelehnt wurde oder der Knoten kein Element ist, -2 wenn die Seite nicht antwortete |
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 (of_get_last_error() sagt warum), -5 bei leerem Argument, -2 wenn die Seite nicht antwortete. Was eine Änderung schreibt, folgt der Regel des Builders: die Steuerzeichen, die XML verbietet, werden entfernt, und ein CR wird so geschrieben, dass er sich zurücklesen lässt.
| Element | Rolle |
|---|---|
of_set_value (string as_xpath, string as_text) → long | Setzt den Text des ersten passenden Knotens (seine Kinder werden ersetzt). Überladungen: decimal, date, datetime, boolean, geschrieben wie bei of_leaf |
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, of_get_last_error()) |
of_remove_attr (string as_xpath, string as_name) → long | Entfernt ein Attribut vom ersten passenden Knoten; -4 und „no such attribute“, wenn der Knoten es nicht hat |
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); ein mit of_register_namespace gebundenes oder an anderer Stelle im Dokument deklariertes Präfix deklariert ebenfalls 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 of_get_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 über MSXML per OLE: Msxml2.DOMDocument.6.0, transformNode). 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_close verliert sie nicht |
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. Dafür wird keine Seite geöffnet |
// Local variables
n_pbt_xml lnv_xml
string ls_soap, ls_ok, ls_name, ls_out
// ls_soap holds the response of a web service
lnv_xml = create n_pbt_xml
// 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()
// Free the object
destroy lnv_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 (of_get_last_error() sagt, warum) |
of_is_open ( ) → boolean | Wahr, sobald die verborgene Seite existiert |
of_close ( ) → long | 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, mit den durch of_register_namespace gebundenen Präfixen. Wird beim Zerstören für Sie erledigt Liefert 0, sobald erledigt. |
of_reset ( ) → long | Zurück zu den Standardwerten: der Builder geleert, das geladene Dokument verworfen, die registrierten Präfixe vergessen, of_get_last_error() geleert. Die verborgene Seite bleibt offen; of_close gibt sie frei Liefert 0, sobald erledigt. |
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.