xmltree — u_pbt_xmltree #
← Referencia de componentes · Índice de la guía
xmltree muestra un valor XML como un árbol plegable, coloreado: una pantalla de configuración, una respuesta de API, una depuración de integración. Fija el texto XML en
is_xml, el componente lo muestra; un clic en un nodo reporta su ruta (ue_node_clicked), un XML inválido lanzaue_error. No modifica nada: es un VISOR.
▶ Verlo en vivo — Aplicación de demostración, mosaico XML tree, con el código y esta página lado a lado.
De un vistazo #
| Userobject | u_pbt_xmltree |
| Entrada | El texto XML, en is_xml (una cadena) |
| Plegar / desplegar | Cada elemento con su marcador + / − en el margen de los números, por su ruta (of_expand_path, of_collapse_path), o todo de una vez (of_expand_all, of_collapse_all) |
| Retorno | Un clic en un nodo da su ruta (ue_node_clicked), un XPath que n_pbt_xml lee tal cual: /order/lines/line[2], /order/@id para un atributo, /order/comment()[1] para un comentario — cada línea tiene la suya; un XML inválido lanza ue_error y muestra el origen, con la línea errónea marcada |
| Fidelidad | Cada nodo en su sitio, en el orden del documento: el texto entre dos hijos, las secciones CDATA, los comentarios, las instrucciones de procesamiento, la declaración XML |
Inicio rápido #
// Show an XML response as a tree
uo_xml.is_xml = inv_rest.of_response_text()
// Fold everything, then let the user open what interests them
uo_xml.of_collapse_all()
// ue_node_clicked : the path of the node clicked, an XPath ("/order/lines/line[2]",
// "/order/@id" for an attribute) -> n_pbt_xml.of_get_value(as_path) reads its value
Propiedades #
| Propiedad | Tipo | Predeterminado | Descripción |
|---|---|---|---|
is_xml | string | "" | El texto XML a mostrar, leído y mostrado como un árbol: cada nodo en su sitio. Vacío borra el árbol, sin error; un XML inválido lanza ue_error y muestra el origen alrededor de la línea errónea. Se relee tal como se asignó, incluso un texto inválido. Un documento nuevo empieza sin selección y todo abierto: of_get_layout antes y of_set_layout después conservan lo que el usuario había abierto |
ib_wrap | boolean | true | Las líneas largas se ajustan (true, por defecto) o se quedan en una línea con barra horizontal (false) — un aspecto de editor de código |
ib_search_enabled | boolean | true | Ctrl+F en el árbol abre un cuadro de búsqueda — la misma búsqueda que of_search: escribir resalta, Intro o F3 siguiente, Mayús+Intro o Mayús+F3 anterior, Esc cierra. false deja el atajo a una aplicación que busca desde su propio cuadro. El cuadro lleva tres botones antes del contador, Aa (ib_find_match_case), ab (ib_find_whole_word) y & (ib_find_decoded); cambiar una opción relanza la búsqueda en curso desde su primera aparición |
ib_find_match_case | boolean | false | Opción de búsqueda: solo encuentra el texto con las mismas mayúsculas y minúsculas. El botón Aa del cuadro de búsqueda (Ctrl+F) es el mismo interruptor; vale para of_search y para lo que el usuario escribe. Leída en directo; of_reset la devuelve a false |
ib_find_whole_word | boolean | false | Opción de búsqueda: solo encuentra el texto como palabra completa (una letra, una cifra o un _ al lado forma parte de la palabra: id no se encuentra ni en user_id ni en ids). El botón ab del cuadro de búsqueda es el mismo interruptor. Leída en directo; of_reset la devuelve a false |
ib_find_decoded | boolean | false | Opción de búsqueda: busca en los VALORES decodificados — un texto y un valor de atributo leídos como los lee n_pbt_xml (Durand & Co encuentra Durand & Co, x < y encuentra x < y); el resaltado cubre el escape entero. false busca el texto tal como se muestra. El botón & del cuadro de búsqueda es el mismo interruptor. Leída en directo; of_reset la devuelve a false |
is_theme_style | string | "" | Estilo visual del componente (constantes THEME_STYLE_*); vacío = el de la aplicación, seguido en cada cambio |
is_theme_mode | string | "" | Variante clara u oscura (constantes THEME_MODE_*); vacío = la de la aplicación, seguida en cada cambio |
il_theme_accent | long | -1 | Color de acento de este componente (-1 = acento de la aplicación, o el del tema) |
is_tooltip | string | "" | Tooltip simple mostrado al pasar el ratón por el componente |
is_super_tooltip_title | string | "" | Título del tooltip enriquecido (prevalece sobre is_tooltip) |
is_super_tooltip_text | string | "" | Texto del tooltip enriquecido (se acepta el marcado enriquecido) |
is_super_tooltip_image | string | "" | Imagen del tooltip enriquecido |
Métodos #
| Método | Descripción |
|---|---|
of_expand_all ( ) → long | Despliega cada elemento. Ningún ue_node_toggled: ningún gesto abre el árbol entero de una vez. Devuelve 0, -2 si el componente no está creado |
of_collapse_all ( ) → long | Pliega cada elemento anidado (la raíz queda visible). Una selección oculta por un pliegue pasa al elemento plegado, y ue_selection_changed lo indica. Ningún ue_node_toggled: ningún gesto pliega el árbol entero de una vez. Devuelve 0, -2 si el componente no está creado |
of_clear ( ) → long | Vacía el árbol (como is_xml = ""); ib_wrap, ib_search_enabled, ib_find_match_case e ib_find_whole_word conservan su valor (es of_reset el que restablece cada propiedad). Devuelve 0, -2 si el componente no está creado |
of_expand_to_level ( long al_level ) → long | Muestra el árbol hasta al_level: los elementos a esa profundidad o más se pliegan (1 = los hijos directos de la raíz, 0 pliega la raíz). Ningún ue_node_toggled; una selección que mueve a un elemento plegado lanza ue_selection_changed. Devuelve 0, -2 si el componente no está creado |
of_expand_path ( string as_path ) → long | Abre UN elemento por su ruta — cualquier XPath, como of_select_path — y los elementos por encima de él para que se vea. Como su marcador +, lanza ue_node_toggled para el elemento y para cada elemento plegado por encima abierto en el camino (nada para un elemento ya abierto). Devuelve 0, -5 si ningún elemento con hijos corresponde, -2 si el componente no está creado |
of_collapse_path ( string as_path ) → long | Pliega UN elemento por su ruta (cualquier XPath). Como su marcador −, lanza ue_node_toggled si el elemento estaba abierto, y ue_selection_changed cuando la selección debe pasar a él. Devuelve 0, -5 si ningún elemento con hijos corresponde, -2 si el componente no está creado |
of_is_expanded ( string as_path ) → boolean | true si el elemento de esa ruta (cualquier XPath) está abierto, leído EN VIVO; false si está plegado, y para un nodo sin hijos o una ruta que no encuentra nada. Lo necesario para guardar lo que el usuario abrió y restablecerlo |
of_get_layout ( ) → string | La disposición del árbol, leída EN VIVO, como texto JSON que guardar: los elementos plegados (collapsed, o expanded cuando esa lista es más corta — todo elemento que no nombra queda entonces plegado), la ruta seleccionada (selected, null sin selección) y la línea en lo alto de la vista (top, una ruta, nunca píxeles). Para devolverla a of_set_layout, también tras un documento nuevo |
of_set_layout ( string as_layout_json ) → long | Devuelve al árbol una disposición dada por of_get_layout: los pliegues (una ruta que el documento ya no tiene se ignora, un elemento nuevo conserva su valor por defecto), la selección (ue_selection_changed, como of_select_path) y la línea de arriba. ue_layout_changed sigue una vez si los pliegues cambiaron. Devuelve 0, -5 si el texto no es un objeto JSON, -2 si el componente no está creado |
of_search ( string as_query ) → long | Resalta cada aparición (sin distinguir mayúsculas por defecto — véase ib_find_match_case —, solo palabras completas con ib_find_whole_word) y salta a la primera; solo se abren los elementos que ocultan la aparición ACTUAL, y of_clear_search los vuelve a plegar. ue_search_result dice cuántas. La búsqueda mira el texto tal como se MUESTRA: en un texto, Durand & Co se escribe Durand & Co y se busca así (una sección CDATA lo muestra tal cual) — con ib_find_decoded, en los valores decodificados, donde Durand & Co encuentra ambos. Una consulta vacía es of_clear_search; una búsqueda termina un of_find_xpath. El cuadro de búsqueda se abre con la consulta dentro y el foco en él (el mismo que Ctrl+F): Intro pasa a la siguiente; con ib_search_enabled a false, el árbol solo resalta. Devuelve 0, o un código negativo |
of_search_next ( ) → long | Pasa a la SIGUIENTE coincidencia (vuelve a la primera tras la última); durante un of_find_xpath, al nodo siguiente, que se selecciona. ue_search_result informa la nueva posición. Devuelve 0, o un código negativo |
of_search_prev ( ) → long | Pasa a la coincidencia ANTERIOR (vuelve a la última antes de la primera); durante un of_find_xpath, al nodo anterior, que se selecciona. ue_search_result informa la nueva posición. Devuelve 0, o un código negativo |
of_clear_search ( ) → long | Borra la búsqueda, o el of_find_xpath: ya no hay resaltado ni coincidencia actual (of_match_count devuelve 0), el cuadro de búsqueda se vacía y se cierra, y los elementos que la búsqueda abrió se vuelven a plegar como antes. Devuelve 0, o un código negativo |
of_find_xpath ( string as_xpath ) → long | Resalta CADA nodo del árbol que un XPath designa (//line, //line[@qty > 1], //@sku) y selecciona el primero; of_search_next / of_search_prev (y F3) los recorren, cada uno seleccionado, y ue_search_result los cuenta. Una búsqueda de texto, of_clear_search, Ctrl+F o un documento nuevo la terminan. Devuelve el número de nodos encontrados (0 si ninguno), -5 si el texto no es un XPath de nodos (un error de sintaxis, un número como count(…), un prefijo desconocido), -2 si el componente no está creado. Un texto vacío equivale a of_clear_search |
of_select_path ( string as_path ) → long | Selecciona y desplaza hasta el nodo en as_path; como el teclado, lanza ue_selection_changed (nada si el nodo ya está seleccionado); los elementos plegados que lo ocultan se abren. as_path es CUALQUIER XPath 1.0 que designe un nodo del árbol: una ruta tal como la da el árbol (/order/@id), //line[@sku='A'], /order/lines/line[1], otro prefijo ligado al mismo espacio de nombres; se selecciona el primer nodo encontrado que el árbol MUESTRA (un espacio de maquetación no tiene línea), y of_selected_path da luego la ruta del árbol. Devuelve 0, -5 si ningún nodo del árbol corresponde (la selección no se mueve), -2 si el componente no está creado |
of_selected_path ( ) → string | La ruta del nodo seleccionado, leída EN DIRECTO: una ruta XPath 1.0 para pasar tal cual a n_pbt_xml.of_get_value sobre el mismo documento. CADA línea tiene la suya: /order/lines/line[2] cuando un nombre se repite, /order/@id para un atributo, /p/text()[2] para un texto, /order/comment()[1], /order/processing-instruction('x')[1], /comment()[1] antes de la raíz. Un elemento de un espacio de nombres POR DEFECTO se escribe *[local-name()='Body'] — un nombre desnudo no encuentra nada en XPath; un nombre con prefijo (soap:Body) se conserva cuando su prefijo designa el mismo espacio de nombres, si no el paso nombra también el espacio (namespace-uri()). Una etiqueta de cierre da su elemento. Vacío si no hay nada seleccionado, y para la declaración XML o el DOCTYPE (que no son nodos) |
of_selected_value ( ) → string | El valor de la selección, leído EN DIRECTO y decodificado — lo que n_pbt_xml.of_get_value lee en of_selected_path: el valor de un atributo, el texto de un elemento HOJA (CDATA incluido, espacios conservados), el texto de una línea de texto, de un comentario o de una instrucción de procesamiento; un elemento mostrado <x/> que solo contiene saltos de línea los devuelve, como n_pbt_xml. Vacío para un elemento con hijos, o sin selección |
of_selected_xml ( ) → string | El XML del nodo seleccionado, leído EN DIRECTO: un elemento con todo lo que contiene, un atributo con la forma name="value", un texto escapado, un comentario, un CDATA o una instrucción de procesamiento tal como están escritos — lo que se copia de un editor XML. Vacío sin selección |
of_selected_kind ( ) → string | Qué es el nodo seleccionado, leído EN DIRECTO: KIND_ELEMENT, KIND_ATTRIBUTE, KIND_TEXT, KIND_CDATA, KIND_COMMENT, KIND_PI (una instrucción de procesamiento), KIND_DECLARATION (la declaración XML) o KIND_DOCTYPE. Vacío sin selección |
of_selected_name ( ) → string | El nombre cualificado del nodo seleccionado, leído EN DIRECTO: un elemento o un atributo tal como está escrito (soap:Body, id), el destino de una instrucción de procesamiento. Vacío para un texto, un CDATA, un comentario, la declaración, el DOCTYPE, o sin selección |
of_selected_namespace ( ) → string | La URI del espacio de nombres del elemento o del atributo seleccionado, leída EN DIRECTO (http://schemas.xmlsoap.org/soap/envelope/). Vacío si no tiene (un atributo sin prefijo no tiene), para cualquier otro nodo, o sin selección |
of_copy ( ) → long | Pone el XML de la selección en el portapapeles, como Ctrl+C en el árbol (el texto de of_selected_xml); un trozo de texto resaltado con el ratón es lo que copia Ctrl+C. Devuelve 0, -4 si no hay nada seleccionado, -2 si el componente no está creado |
of_copy_path ( ) → long | Pone la RUTA del nodo seleccionado en el portapapeles (/order/lines/line[2], /order/@id), un XPath listo para n_pbt_xml. Devuelve 0, -4 si no hay nada seleccionado o si el nodo no tiene ruta (la declaración XML, el DOCTYPE), -2 si el componente no está creado |
of_match_count ( ) → long | Devuelve el número de APARICIONES de la búsqueda actual (dos en una línea cuentan dos), leído EN DIRECTO — el 12 de una barra de estado 3 / 12. 0 sin búsqueda |
of_match_index ( ) → long | Devuelve la posición (1-based) de la coincidencia actual, leída EN VIVO — el 3 de una barra de estado 3 / 12. 0 sin coincidencia |
Eventos #
| Evento | Cuándo |
|---|---|
ue_node_clicked (string as_path) | El usuario hizo clic en un nodo, o pulsó Intro en una hoja seleccionada: su XPath (/order/lines/line[2]); un atributo, un texto, un comentario o una instrucción de procesamiento da el suyo (/order/@id, /order/comment()[1]), una etiqueta de cierre su elemento. Para pasar a n_pbt_xml.of_get_value sobre el mismo documento |
ue_node_toggled (string as_path, boolean ab_expanded) | Un elemento se ha plegado (ab_expanded = false) o abierto (true): por el usuario (su marcador + / −, las flechas, Intro o Espacio) o por of_expand_path / of_collapse_path. of_expand_all, of_collapse_all y of_expand_to_level no lo lanzan: ningún gesto pliega el árbol entero |
ue_node_rclicked (string as_path, long al_x, long al_y) | Clic derecho en un nodo, o tecla Menú (Mayús+F10) en el árbol: el nodo se selecciona primero (ue_selection_changed si la selección se movió), as_path es su ruta, al_x / al_y el punto en la PANTALLA, en píxeles. Abra ahí su propio menú (un u_pbt_contextmenu): el árbol no tiene |
ue_layout_changed (string as_layout_json) | Los pliegues cambiaron — un gesto, una orden de su código (of_collapse_all incluido), un documento nuevo, of_set_layout: as_layout_json es la disposición entera, como la da of_get_layout, lista para guardar. Un cambio de selección o de desplazamiento no lo lanza |
ue_selection_changed (string as_path) | La selección se movió sin clic, por el usuario o por su código: flechas, Inicio/Fin, Re Pág/Av Pág, of_select_path, un paso de of_find_xpath, o un pliegue que oculta la línea seleccionada (la selección pasa al elemento plegado). Solo se lanza cuando la selección cambia de verdad; un documento nuevo empieza sin selección y no lo lanza — un clic de ratón informa ue_node_clicked |
ue_search_result (long al_count, long al_index) | Una búsqueda empezó o avanzó: al_count apariciones en total, la actual es al_index (desde 1, 0 si ninguna) — lo necesario para mostrar « 3 / 12 »; of_find_xpath también lo lanza (al_count = los nodos encontrados), y (0, 0) cuando termina; cuando una búsqueda se cierra (Esc en el cuadro, of_clear_search, of_reset, ib_search_enabled = false), (0, 0) una vez |
ue_error (string as_message) | El texto en is_xml no es un XML válido: el mensaje dice dónde, en el idioma de visualización (« XML no válido: línea 3, columna 16 (…) », el detalle del motor entre paréntesis), y el árbol muestra el origen alrededor de esa línea, con la línea errónea marcada. Se lanza también cuando el documento es demasiado grande para mostrarse |
Ejemplo #
Explorar la respuesta de una API #
// Show the XML an API answered, or nothing if the call failed
if inv_rest.of_get(/*url*/ "https://api.example.com/orders/4152") = 200 then
uo_xml.is_xml = inv_rest.of_response_text()
uo_xml.of_collapse_all() // the reader opens what interests them
else
uo_xml.of_clear()
end if
Leer el valor de un nodo pulsado #
// Instance variable of the window : the answer, loaded ONCE by n_pbt_xml
n_pbt_xml inv_xml
// open event of the window : n_pbt_xml is created once, owned by the window
inv_xml = create n_pbt_xml
inv_xml.ipo_owner = this
// When the answer arrives : the tree shows it, n_pbt_xml loads the same text once
uo_xml.is_xml = inv_rest.of_response_text()
inv_xml.of_load(/*xml*/ inv_rest.of_response_text())
// ue_node_clicked of uo_xml : the value at the clicked path, nothing loaded again
st_value.text = inv_xml.of_get_value(/*xpath*/ as_path)
// or, without a second parser : the value of the selection, decoded
st_value.text = uo_xml.of_selected_value()
Buscar palabras completas, con mayúsculas #
// Whole words only, with the same case : "id" is not found inside "user_id"
uo_xml.ib_find_match_case = true
uo_xml.ib_find_whole_word = true
uo_xml.of_search(/*query*/ "id")
Conservar los pliegues cuando se actualiza la respuesta #
// Local variables
string ls_layout
// The folds, the selected node and the line at the top, kept before the new text
ls_layout = uo_xml.of_get_layout()
uo_xml.is_xml = inv_rest.of_response_text()
// The same elements fold again ; a path the new text no longer has is ignored
uo_xml.of_set_layout(/*layout_json*/ ls_layout)
Encontrar cada nodo de un XPath #
// Local variables
long ll_found
// Every order line of more than one item : highlighted, the first one selected
ll_found = uo_xml.of_find_xpath(/*xpath*/ "//line[@qty > 1]")
// A Next button walks them, like F3 ; ue_search_result feeds a "2 / 5" status line
if ll_found > 1 then uo_xml.of_search_next()
// What is selected, without a second parser
st_kind.text = uo_xml.of_selected_kind() + " " + uo_xml.of_selected_name()
Un menú sobre un nodo #
// ue_node_rclicked of uo_xml : the node is selected, open YOUR menu at that point of the screen
uo_menu.of_show(/*x*/ al_x, /*y*/ al_y)
// ue_item_selected of uo_menu : copy the XML of the node, or its path for n_pbt_xml
choose case as_keys
case "copy"
uo_xml.of_copy()
case "copypath"
uo_xml.of_copy_path()
end choose
Buenas prácticas #
- Es un visor, no un editor: muestra el XML, no lo cambia. Para leer un valor, pase la ruta de
ue_node_clickedan_pbt_xml.of_get_valuesobre el mismo texto, o leaof_selected_value. - Un XML grande sigue fluido: solo se dibujan las líneas en pantalla, una exportación de varios miles de líneas se recorre con el teclado sin esperas. Primero
of_collapse_allsigue siendo lo más legible. - Un XML inválido no rompe nada:
ue_errorlo dice (con la línea y la columna del fallo, en el idioma de visualización), y el árbol muestra el origen alrededor de la línea errónea. Es el retorno a mostrar, no un fallo. - Un espacio de nombres por defecto (
xmlns="urn:…", una respuesta SOAP): la ruta se escribe*[local-name()='Body'], la única forma que un XPath sin prefijo registrado sabe leer; un prefijo redeclarado con otro URI, o un hermano del mismo nombre en otro espacio, se escribe*[local-name()='x' and namespace-uri()='urn:…'].@xml:langse lee tal cual. Una declaraciónxmlnsse muestra pero no tiene ruta: XPath no la ve como un atributo. - Lo que se muestra es XML: el valor de un atributo conserva sus comillas y sus saltos de línea codificados (
), un texto sus&y<y sus espacios significativos; solo desaparecen los saltos de línea de maquetación alrededor de un texto. Un espacio entre dos hijos (el espacio de<b>x</b> <i>y</i>) tiene su propia línea, mostrada ␠: forma parte del texto. - Con el teclado: las flechas pasan de línea en línea, Flecha derecha recorre los atributos de una etiqueta antes de bajar, Av Pág avanza una pantalla (una sección CDATA de trescientas líneas cuenta por su altura), Ctrl+C copia el XML de la selección.
- De derecha a izquierda: un documento XML es un texto de izquierda a derecha, el árbol sigue así en una aplicación RTL (solo el cuadro de búsqueda sigue la dirección de la aplicación).
Heredado de la base común #
Estos miembros existen en todos los componentes visuales — no son propios de este. Se detallan una sola vez, en los capítulos transversales; esta tabla solo dice dónde leerlos.
| Miembros | Función | Detallado en |
|---|---|---|
of_reset | Poner el componente a cero | 3.6 Poner un componente a cero: of_reset() |
of_register_shortcut · of_clear_shortcuts | Atajos de teclado del componente | 3.5 Los atajos de teclado |
of_is_created · of_is_ready · of_get_last_error | Si ha nacido, si está listo, qué ha fallado | 3.7 Diagnóstico |
of_save_as_png · of_save_as_jpg | Exportar el render como imagen | 3.8 Exportar la representación como imagen |
of_set_redraw | Agrupar los cambios en un solo repintado | 3.10 Buenas prácticas |
of_preload_icons | Iconos mostrados sin retardo | Visualización instantánea: of_icon |
of_set_translation | Traducir una etiqueta del componente | 5.2 Adaptar una etiqueta: of_set_translation |
of_focus_webview | Dar el foco al componente | 6.4 Teclado y foco |
of_print · of_print_to_pdf | Imprimir, o escribir un PDF | 6.9 Imprimir |
of_set_property · of_get_property · of_component_name | Controlar una propiedad por su nombre | 3.1 El motor de propiedades |
is_accessible_name · is_accessible_description | El nombre y la descripción que dice un lector de pantalla | 3.4 Propiedades y eventos opcionales |