xml — n_pbt_xml #
← Referência dos componentes · Índice do guia
Escrever um XML elemento a elemento — aberturas, atributos, texto, fechos — com o escape feito por si, e depois ler um com XPath real:
of_load,of_get_value,of_get_attr,of_count. O PowerBuilder 10 não tem analisador XML; este assenta no DOMParser e no document.evaluate do motor WebView2, chamados de forma síncrona.
▶ Ver ao vivo — Aplicação de demonstração, mosaico XML: os resultados, o código que os produz e esta página, lado a lado.
Em resumo #
O lado de construção é PowerScript puro (montar uma string não precisa de motor). O lado de leitura abre uma página oculta na primeira consulta. O XPath é a versão 1.0, tal como o navegador o avalia. Há um documento de cada vez: uma leitura sobre um documento construído carrega-o primeiro na página, ele torna-se o documento carregado, e o of_start_element seguinte começa um novo. Uma leitura é recusada enquanto um elemento do documento construído ainda estiver aberto (-4, vazio ou false, e is_last_error): feche primeiro os seus elementos — nada se perde. of_xml e of_pretty, que trabalham sobre uma cópia, continuam disponíveis.
Início rápido #
// 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
Propriedades #
| Propriedade | Tipo | Predefinição | Função |
|---|---|---|---|
is_last_error | string | "" | Porque a última leitura devolveu vazio, false, 0 ou um código negativo: documento malformado, XPath recusado pelo motor, XPath sem correspondência, nada carregado, limite demo, página que não respondeu. Vazio após uma leitura bem-sucedida. O builder também escreve aqui quando recusa um nome de elemento ou de atributo inválido |
ipo_owner | powerobject | null | O objeto visual para o qual este utilitário trabalha: a licença verifica-se na sua classe. Define-se antes da primeira leitura; definido mais tarde, é transmitido na leitura seguinte. Necessário apenas na aplicação de demonstração; uma chave de desenvolvimento ou de execução desbloqueia a leitura sem ele. Não desbloqueada, a leitura está em modo demo — documentos de 64 KB no máximo, alterações incluídas. A construção não precisa dele: é PowerScript puro |
Construir um documento #
| Membro | Função |
|---|---|
of_start_element (string as_name) | Abre um elemento (os elementos aninham-se: uma tag aberta é fechada primeiro). Um nome inválido (vazio, com um espaço, um carácter proibido, mais de um :, um : no início ou no fim) é recusado: is_last_error diz porquê, e o elemento fica fora do documento com tudo o que contém |
of_element_attr (string as_name, string as_value) | Adiciona um atributo ao elemento aberto, valor escapado — quebras de linha e tabulações incluídas, para que se releiam tal como estavam (antes de qualquer filho ou texto). Um nome inválido é recusado (is_last_error); o mesmo nome dado duas vezes mantém UM só atributo, com o segundo valor |
of_element_text (string as_text) | O conteúdo de texto do elemento atual, escapado; os caracteres de controlo que o XML proíbe são retirados (um só tornava todo o documento malformado) |
of_end_element ( ) | Fecha o elemento atual (vazio, é auto-fechado <name/>) |
of_leaf (string as_name, string as_text) | Um elemento folha numa chamada — <name>texto</name>, com escape |
of_clear ( ) → long | Esvazia o documento — construído ou carregado — para começar outro; um documento carregado sai também da página. Devolve 0 |
of_xml ( ) → string | O documento tal como está: o que construiu ou carregou (of_load), após qualquer alteração — a saída única, para enviar, guardar ou reescrever. Um documento construído não precisa de página (qualquer elemento aberto é fechado) ; um carregado é serializado pelo motor. of_pretty é a forma indentada |
Ler um documento (XPath) #
| Membro | Função |
|---|---|
of_load (string as_xml) → long | Carrega um texto XML (analisado pelo DOMParser do motor). Devolve 0 se bem formado, -5 se vazio, -4 se XML inválido (ou, em modo demo, demasiado longo depois de expandidas as entidades), -2 se a página oculta não respondeu. Num código negativo NADA fica: nem um documento carregado antes, nem um construído a meio |
of_is_valid ( ) → boolean | Verdadeiro quando há um documento bem formado — carregado com of_load, ou construído (é então carregado na página, como em qualquer leitura). Falso quando não há nada, ou quando o documento construído está malformado ou ainda tem um elemento aberto |
of_exists (string as_xpath) → boolean | Verdadeiro quando o XPath corresponde a pelo menos um nó. Uma expressão que devolve um VALOR (count(//line)) não é um nó: leia-a com of_get_value |
of_get_value (string as_xpath) → string | O conteúdo de texto do PRIMEIRO nó correspondente. Vazio se nenhum (is_last_error di-lo). Um XPath que devolve um VALOR dá-o como texto: count(//line) → 3, sum(//@qty), boolean(//paid) → true |
of_get_attr (string as_xpath, string as_name) → string | O valor do atributo as_name no primeiro nó correspondente. Vazio se ausente |
of_count (string as_xpath) → long | Quantos nós o XPath seleciona. 0 se nenhum (uma contagem XPath nunca é negativa); is_last_error diz quando o próprio XPath foi recusado |
of_name (string as_xpath) → string | O nome da tag do primeiro nó correspondente. Vazio se nenhum |
of_pretty ( ) → string | O documento tal como está — construído ou carregado, o que of_xml devolve — reindentado para leitura. Nada se perde: CDATA, comentários, instruções de processamento e a declaração XML são mantidos, e um elemento que contém texto é escrito numa linha, tal como está. Vazio quando não há nada, ou quando um documento construído não está bem formado |
Vários nós, e o documento #
| Membro | Função |
|---|---|
of_get_values (string as_xpath, ref string as_values[]) → long | O conteúdo de texto de CADA nó correspondente, em as_values; devolve a contagem. Onde of_get_value só devolve o primeiro |
of_get_attrs (string as_xpath, string as_name, ref string as_values[]) → long | O valor do atributo as_name em CADA nó correspondente (o id de cada linha); devolve a contagem |
of_get_attr_names (string as_xpath, ref string as_names[]) → long | Os nomes de todos os atributos do primeiro nó correspondente (enumeração); devolve a contagem |
Modificar um documento #
O lado de escrita altera a árvore carregada no lugar; of_xml devolve o resultado. Cada uma visa o PRIMEIRO nó correspondente (exceto of_remove, que os toma todos), devolve 0 em sucesso, -4 quando nada corresponde ou a alteração é recusada (is_last_error diz porquê), -5 num argumento vazio, -2 se a página não respondeu.
| Membro | Função |
|---|---|
of_set_value (string as_xpath, string as_text) → long | Define o texto do primeiro nó correspondente (os seus filhos são substituídos) |
of_set_attr (string as_xpath, string as_name, string as_value) → long | Define (ou adiciona) um atributo no primeiro nó correspondente. Um nome com prefixo (xsi:type) vai para o espaço de nomes que o prefixo tem nesse nó (ou ligado por of_register_namespace); um prefixo não ligado em lado nenhum é recusado (-4, is_last_error) |
of_remove_attr (string as_xpath, string as_name) → long | Remove um atributo do primeiro nó correspondente |
of_add_child (string as_xpath, string as_tag, string as_text) → long | Acrescenta um elemento filho <as_tag>as_text</as_tag> sob o primeiro nó correspondente (o filho herda o espaço de nomes e o prefixo do pai; uma tag com prefixo p:item toma o espaço de nomes do seu prefixo, ou -4 se não estiver ligado em lado nenhum). -4 também quando o nó não pode ter filhos (um atributo, um texto) ou a tag não é um nome válido |
of_add_xml (string as_xpath, string as_fragment) → long | Enxerta um fragmento XML já formado (um ou vários elementos irmãos) sob o primeiro nó correspondente — o que of_add_child não faz, tomando apenas uma etiqueta e um texto. O fragmento deve estar bem formado; herda os espaços de nomes em vigor no seu alvo, como of_add_child (<line> sob <order xmlns='urn:acme'> está em urn:acme, <s:Item/> sob um s:Body SOAP não declara nada) |
of_remove (string as_xpath) → long | Retira TODOS os nós correspondentes (uma linha, um ramo obsoleto, um atributo). Devolve quantos foram realmente retirados (>= 0; em 0, is_last_error diz porquê), -4 se nada estiver carregado, -5 num XPath vazio, -2 se a página não respondeu. O elemento raiz fica: of_clear esvazia um documento |
Espaços de nomes #
Um XPath com prefixo (SOAP, uma API empresarial) resolve sozinho um prefixo que o documento declara (xmlns:s="…", em qualquer elemento). ⚠️ A armadilha mais frequente: o espaço de nomes POR OMISSÃO. <order xmlns="urn:acme"><customer>… não tem prefixo, e no entanto /order/customer não corresponde a NADA: o XPath 1.0 não tem espaço de nomes por omissão. Ligue um prefixo à sua escolha com of_register_namespace("a", "urn:acme") e escreva /a:order/a:customer. of_clear_namespaces esquece as ligações. Não há XSLT: o Chromium retira-o do motor (transforme no servidor ou em PowerScript). Não há validação por esquema XSD: o motor não a tem.
| Membro | Função |
|---|---|
of_register_namespace (string as_prefix, string as_uri) → long | Liga um prefixo ao URI do seu espaço de nomes, para que um XPath com prefixo se resolva. Devolve 0, -5 num prefixo ou URI vazio, -2 se a página não respondeu. As ligações duram até of_clear_namespaces ou of_reset |
of_clear_namespaces ( ) → long | Esquece todos os prefixos registados: um prefixo que o documento não declara deixa de corresponder a nada enquanto não for ligado. Devolve 0, -2 se a página não respondeu |
// 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()
A página oculta #
| Membro | Função |
|---|---|
of_open ( ) → long | Cria a página oculta (lado leitura). Facultativo — a primeira leitura fá-lo. Devolve o handle (> 0) ou -2 se não foi possível criá-la (is_last_error diz porquê) |
of_is_open ( ) → boolean | Verdadeiro assim que a página oculta existe |
of_close ( ) | Liberta a página oculta. A construção continua sem ela, e um documento carregado não se perde: é guardado como texto, e a leitura seguinte volta a carregá-lo. Feito por si na destruição |
of_reset ( ) | Regresso aos valores por omissão: o builder esvaziado, o estado de leitura limpo |
Âmbito. O XML lê-se através do motor (DOMParser, XPath):
n_pbt_xmlabre uma página oculta na primeira leitura, ao contrário de json, que analisa em PowerScript puro. Para mostrar um XML como árvore recolhível, veja xmltree.