PBToolboxAI v5 ← Site

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 lanza ue_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 #

Userobjectu_pbt_xmltree
EntradaEl texto XML, en is_xml (una cadena)
Plegar / desplegarCada 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)
RetornoUn 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
FidelidadCada 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 #

PropiedadTipoPredeterminadoDescripción
is_xmlstring""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_wrapbooleantrueLas 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_enabledbooleantrueCtrl+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_casebooleanfalseOpció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_wordbooleanfalseOpció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_decodedbooleanfalseOpció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 &amp; Co, x < y encuentra x &lt; 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_stylestring""Estilo visual del componente (constantes THEME_STYLE_*); vacío = el de la aplicación, seguido en cada cambio
is_theme_modestring""Variante clara u oscura (constantes THEME_MODE_*); vacío = la de la aplicación, seguida en cada cambio
il_theme_accentlong-1Color de acento de este componente (-1 = acento de la aplicación, o el del tema)
is_tooltipstring""Tooltip simple mostrado al pasar el ratón por el componente
is_super_tooltip_titlestring""Título del tooltip enriquecido (prevalece sobre is_tooltip)
is_super_tooltip_textstring""Texto del tooltip enriquecido (se acepta el marcado enriquecido)
is_super_tooltip_imagestring""Imagen del tooltip enriquecido

Métodos #

MétodoDescripción
of_expand_all ( ) → longDespliega 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 ( ) → longPliega 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 ( ) → longVací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 ) → longMuestra 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 ) → longAbre 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 ) → longPliega 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 ) → booleantrue 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 ( ) → stringLa 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 ) → longDevuelve 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 ) → longResalta 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 &amp; 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 ( ) → longPasa 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 ( ) → longPasa 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 ( ) → longBorra 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 ) → longResalta 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 ) → longSelecciona 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 ( ) → stringLa 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 ( ) → stringEl 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 ( ) → stringEl 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 ( ) → stringQué 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 ( ) → stringEl 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 ( ) → stringLa 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 ( ) → longPone 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 ( ) → longPone 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 ( ) → longDevuelve 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 ( ) → longDevuelve 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 #

EventoCuá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 #


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.

MiembrosFunciónDetallado en
of_resetPoner el componente a cero3.6 Poner un componente a cero: of_reset()
of_register_shortcut · of_clear_shortcutsAtajos de teclado del componente3.5 Los atajos de teclado
of_is_created · of_is_ready · of_get_last_errorSi ha nacido, si está listo, qué ha fallado3.7 Diagnóstico
of_save_as_png · of_save_as_jpgExportar el render como imagen3.8 Exportar la representación como imagen
of_set_redrawAgrupar los cambios en un solo repintado3.10 Buenas prácticas
of_preload_iconsIconos mostrados sin retardoVisualización instantánea: of_icon
of_set_translationTraducir una etiqueta del componente5.2 Adaptar una etiqueta: of_set_translation
of_focus_webviewDar el foco al componente6.4 Teclado y foco
of_print · of_print_to_pdfImprimir, o escribir un PDF6.9 Imprimir
of_set_property · of_get_property · of_component_nameControlar una propiedad por su nombre3.1 El motor de propiedades
is_accessible_name · is_accessible_descriptionEl nombre y la descripción que dice un lector de pantalla3.4 Propiedades y eventos opcionales

← Referencia de componentes · Índice de la guía