xml — n_pbt_xml #
← Riferimento dei componenti · Sommario della guida
Scrivere un XML elemento per elemento — aperture, attributi, testo, chiusure — con l'escaping fatto per te, poi rileggerne uno con vero XPath:
of_load,of_get_value,of_get_attr,of_count. PowerBuilder 10 non ha un parser XML; questo si appoggia a DOMParser e document.evaluate del motore WebView2, chiamati in modo sincrono.
▶ Vederlo dal vivo — Applicazione dimostrativa, riquadro XML: i risultati, il codice che li produce e questa pagina, fianco a fianco.
In breve #
Il lato build è PowerScript puro (assemblare una stringa non richiede motore). Il lato lettura apre una pagina nascosta alla prima query. L'XPath è la versione 1.0, come la valuta il browser. C'è un documento alla volta: una lettura su un documento costruito lo carica prima nella pagina, diventa il documento caricato, e il of_start_element seguente ne inizia uno nuovo. Una lettura è rifiutata finché un elemento del documento costruito è ancora aperto (-4, vuoto o false, e is_last_error): chiudete prima i vostri elementi — nulla va perso. of_xml e of_pretty, che lavorano su una copia, restano disponibili.
Avvio rapido #
// 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
Proprietà #
| Proprietà | Tipo | Predefinito | Ruolo |
|---|---|---|---|
is_last_error | string | "" | Perché l'ultima lettura ha reso vuoto, false, 0 o un codice negativo: documento non valido, XPath rifiutato dal motore, XPath senza corrispondenza, niente caricato, limite demo, pagina che non ha risposto. Vuoto dopo una lettura riuscita. Anche il builder vi scrive quando rifiuta un nome di elemento o di attributo non valido |
ipo_owner | powerobject | null | L'oggetto visuale per cui lavora questo helper: la licenza si verifica sulla sua classe. Da impostare prima della prima lettura; impostato più tardi, viene trasmesso alla lettura successiva. Necessario solo nell'applicazione dimostrativa; una chiave di sviluppo o di runtime sblocca la lettura senza di esso. Non sbloccata, la lettura è in modalità demo — documenti di al più 64 KB, modifiche comprese. La costruzione non ne ha bisogno: è PowerScript puro |
Costruire un documento #
| Membro | Ruolo |
|---|---|
of_start_element (string as_name) | Apre un elemento (gli elementi si annidano: un tag aperto viene chiuso prima). Un nome non valido (vuoto, con uno spazio, un carattere vietato, più di un :, un : all'inizio o alla fine) è rifiutato: is_last_error dice perché, e l'elemento resta fuori dal documento con tutto ciò che contiene |
of_element_attr (string as_name, string as_value) | Aggiunge un attributo all'elemento aperto, valore con escape — a capo e tabulazioni compresi, perché si rileggano tali e quali (prima di ogni figlio o testo). Un nome non valido è rifiutato (is_last_error); lo stesso nome dato due volte tiene UN solo attributo, con il secondo valore |
of_element_text (string as_text) | Il contenuto testuale dell'elemento corrente, con escape; i caratteri di controllo vietati da XML sono rimossi (uno solo rendeva non valido tutto il documento) |
of_end_element ( ) | Chiude l'elemento corrente (vuoto, si auto-chiude <name/>) |
of_leaf (string as_name, string as_text) | Un elemento foglia in una chiamata — <name>testo</name>, con escaping |
of_clear ( ) → long | Svuota il documento — costruito o caricato — per iniziarne un altro; un documento caricato lascia anche la pagina. Rende 0 |
of_xml ( ) → string | Il documento così com'è: ciò che hai costruito o caricato (of_load), dopo ogni modifica — l'unica uscita, da inviare, memorizzare o riscrivere. Un documento costruito non necessita di pagina (ogni elemento aperto è chiuso) ; uno caricato è serializzato dal motore. of_pretty è la forma indentata |
Leggere un documento (XPath) #
| Membro | Ruolo |
|---|---|
of_load (string as_xml) → long | Carica un testo XML (analizzato dal DOMParser del motore). Rende 0 se ben formato, -5 se vuoto, -4 se XML non valido (o, in modalità demo, troppo lungo una volta sviluppate le entità), -2 se la pagina nascosta non ha risposto. Su un codice negativo NON resta nulla: né un documento caricato prima, né uno costruito a metà |
of_is_valid ( ) → boolean | Vero quando è tenuto un documento ben formato — caricato con of_load, o costruito (viene allora caricato nella pagina, come da ogni lettura). Falso se non c'è nulla, o se il documento costruito non è ben formato o ha ancora un elemento aperto |
of_exists (string as_xpath) → boolean | Vero quando l'XPath corrisponde ad almeno un nodo. Un'espressione che rende un VALORE (count(//line)) non è un nodo: leggetela con of_get_value |
of_get_value (string as_xpath) → string | Il contenuto testuale del PRIMO nodo corrispondente. Vuoto se nessuno (is_last_error lo dice). Un XPath che rende un VALORE lo rende come testo: count(//line) → 3, sum(//@qty), boolean(//paid) → true |
of_get_attr (string as_xpath, string as_name) → string | Il valore dell'attributo as_name sul primo nodo corrispondente. Vuoto se assente |
of_count (string as_xpath) → long | Quanti nodi seleziona l'XPath. 0 se nessuno (un conteggio XPath non è mai negativo); is_last_error dice quando l'XPath stesso è stato rifiutato |
of_name (string as_xpath) → string | Il nome del tag del primo nodo corrispondente. Vuoto se nessuno |
of_pretty ( ) → string | Il documento così com'è — costruito o caricato, ciò che rende of_xml — reindentato per la lettura. Nulla va perso: CDATA, commenti, istruzioni di elaborazione e dichiarazione XML sono conservati, e un elemento che contiene testo è scritto su una riga, tale e quale. Vuoto se non c'è nulla, o se un documento costruito non è ben formato |
Più nodi, e il documento #
| Membro | Ruolo |
|---|---|
of_get_values (string as_xpath, ref string as_values[]) → long | Il contenuto testuale di OGNI nodo corrispondente, in as_values; restituisce il conteggio. Dove of_get_value rende solo il primo |
of_get_attrs (string as_xpath, string as_name, ref string as_values[]) → long | Il valore dell'attributo as_name su OGNI nodo corrispondente (l'id di ogni riga); restituisce il conteggio |
of_get_attr_names (string as_xpath, ref string as_names[]) → long | I nomi di tutti gli attributi del primo nodo corrispondente (enumerazione); restituisce il conteggio |
Modificare un documento #
Il lato scrittura cambia l'albero caricato sul posto; of_xml ne rende il risultato. Ognuna mira al PRIMO nodo corrispondente (tranne of_remove, che li prende tutti), rende 0 al successo, -4 se nulla corrisponde o se la modifica è rifiutata (is_last_error dice perché), -5 su argomento vuoto, -2 se la pagina non ha risposto.
| Membro | Ruolo |
|---|---|
of_set_value (string as_xpath, string as_text) → long | Imposta il testo del primo nodo corrispondente (i suoi figli sono sostituiti) |
of_set_attr (string as_xpath, string as_name, string as_value) → long | Imposta (o aggiunge) un attributo sul primo nodo corrispondente. Un nome con prefisso (xsi:type) va nello spazio dei nomi che il prefisso ha in quel nodo (o legato con of_register_namespace); un prefisso non legato da nessuna parte è rifiutato (-4, is_last_error) |
of_remove_attr (string as_xpath, string as_name) → long | Rimuove un attributo dal primo nodo corrispondente |
of_add_child (string as_xpath, string as_tag, string as_text) → long | Aggiunge un elemento figlio <as_tag>as_text</as_tag> sotto il primo nodo corrispondente (il figlio eredita lo spazio dei nomi e il prefisso del genitore; un tag con prefisso p:item prende lo spazio dei nomi del suo prefisso, o -4 se non è legato da nessuna parte). -4 anche quando il nodo non può avere figli (un attributo, un testo) o il tag non è un nome valido |
of_add_xml (string as_xpath, string as_fragment) → long | Innesta un frammento XML già formato (uno o più elementi fratelli) sotto il primo nodo corrispondente — ciò che of_add_child non può fare, prendendo solo un tag e un testo. Il frammento deve essere ben formato; eredita gli spazi dei nomi in vigore sul suo bersaglio, come of_add_child (<line> sotto <order xmlns='urn:acme'> è in urn:acme, <s:Item/> sotto un s:Body SOAP non dichiara nulla) |
of_remove (string as_xpath) → long | Rimuove TUTTI i nodi corrispondenti (una riga, un ramo obsoleto, un attributo). Rende quanti ne sono stati davvero rimossi (>= 0; su 0, is_last_error dice perché), -4 se nulla è caricato, -5 su un XPath vuoto, -2 se la pagina non ha risposto. L'elemento radice resta: of_clear svuota un documento |
Namespace #
Un XPath con prefisso (SOAP, un'API aziendale) risolve da solo un prefisso che il documento dichiara (xmlns:s="…", su qualsiasi elemento). ⚠️ La trappola più frequente: lo spazio dei nomi PREDEFINITO. <order xmlns="urn:acme"><customer>… non ha alcun prefisso, eppure /order/customer non corrisponde a NULLA: XPath 1.0 non ha spazio dei nomi predefinito. Legate un prefisso a scelta con of_register_namespace("a", "urn:acme") e scrivete /a:order/a:customer. of_clear_namespaces dimentica i legami. Non c'è XSLT: Chromium lo rimuove dal motore (trasformate lato server o in PowerScript). Non c'è validazione per schema XSD: il motore non ne ha.
| Membro | Ruolo |
|---|---|
of_register_namespace (string as_prefix, string as_uri) → long | Lega un prefisso all'URI del suo spazio dei nomi, perché un XPath con prefisso si risolva. Rende 0, -5 su un prefisso o un URI vuoto, -2 se la pagina non ha risposto. I legami durano fino a of_clear_namespaces o of_reset |
of_clear_namespaces ( ) → long | Dimentica tutti i prefissi registrati: un prefisso che il documento non dichiara non corrisponde più a nulla finché non è legato. Rende 0, -2 se la pagina non ha risposto |
// 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()
La pagina nascosta #
| Membro | Ruolo |
|---|---|
of_open ( ) → long | Crea la pagina nascosta (lato lettura). Facoltativo — la prima lettura lo fa. Restituisce l'handle (> 0) o -2 se non è stato possibile crearla (is_last_error dice perché) |
of_is_open ( ) → boolean | Vero appena la pagina nascosta esiste |
of_close ( ) | Libera la pagina nascosta. Il build continua senza di essa, e un documento caricato non va perso: è conservato come testo, e la lettura seguente lo ricarica. Fatto per voi alla distruzione |
of_reset ( ) | Ritorno ai valori predefiniti: il builder svuotato, lo stato di lettura azzerato |
Ambito. L'XML si legge tramite il motore (DOMParser, XPath):
n_pbt_xmlapre una pagina nascosta alla prima lettura, a differenza di json, che analizza in PowerScript puro. Per mostrare un XML come albero comprimibile, vedi xmltree.