xmltree — u_pbt_xmltree #
← Component reference · Guide contents
xmltree shows a XML value as a collapsible tree, colour-coded: a config screen, an API response, an integration debug. You set the XML text in
is_xml, the component shows it; a click on a node reports its path (ue_node_clicked), invalid XML raisesue_error. It changes nothing: it is a VIEWER.
▶ See it live — Demo application, XML tree tile, with the code and this page side by side.
At a glance #
| Userobject | u_pbt_xmltree |
| Input | The XML text, in is_xml (a string) |
| Fold / unfold | Each element by its + / − marker in the line-number gutter, by its path (of_expand_path, of_collapse_path), or all at once (of_expand_all, of_collapse_all) |
| Feedback | A click on a node gives its path (ue_node_clicked), an XPath n_pbt_xml reads as it is: /order/lines/line[2], /order/@id for an attribute, /order/comment()[1] for a comment — every line has its own; invalid XML raises ue_error and shows the source, the faulty line marked |
| Fidelity | Every node in its place, in document order: text between two children, CDATA sections, comments, processing instructions, the XML declaration |
Quick start #
// 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
Properties #
| Property | Type | Default | Description |
|---|---|---|---|
is_xml | string | "" | The XML text to show, read and displayed as a tree: every node in its place. Empty clears the tree, without an error; invalid XML raises ue_error and shows the source around the faulty line. Reads back exactly as it was set, an invalid text included |
ib_wrap | boolean | true | Long lines wrap (true, the default) or stay on one line with a horizontal scrollbar (false) — a code-editor feel |
ib_search_enabled | boolean | true | Ctrl+F in the tree opens a search box — the same search as of_search: type to highlight, Enter or F3 next, Shift+Enter or Shift+F3 previous, Escape closes. false leaves the shortcut to an application that searches from its own box. The box carries two toggles before the counter, Aa (ib_find_match_case) and ab (ib_find_whole_word); changing an option restarts the current search from its first occurrence |
ib_find_match_case | boolean | false | Search option: finds only the text with the same case. The Aa toggle of the search box (Ctrl+F) is the same switch; applies to of_search and to what the user types. Read live; of_reset puts it back to false |
ib_find_whole_word | boolean | false | Search option: finds the text only as a whole word (a letter, a digit or a _ next to it belongs to the word: id is found neither inside user_id nor inside ids). The ab toggle of the search box is the same switch. Read live; of_reset puts it back to false |
is_theme_style | string | "" | Visual style of the component (THEME_STYLE_* constants); empty = the application's, followed at every change |
is_theme_mode | string | "" | Light or dark variant (THEME_MODE_* constants); empty = the application's, followed at every change |
il_theme_accent | long | -1 | Accent colour of this component (-1 = the application accent, or the theme's) |
is_tooltip | string | "" | Simple tooltip shown when hovering the component |
is_super_tooltip_title | string | "" | Title of the rich tooltip (takes precedence over is_tooltip) |
is_super_tooltip_text | string | "" | Text of the rich tooltip (rich markup accepted) |
is_super_tooltip_image | string | "" | Image of the rich tooltip |
Methods #
| Method | Description |
|---|---|
of_expand_all ( ) → long | Unfolds every element. No ue_node_toggled: no gesture opens the whole tree at once. Returns 0, -2 when the component is not created |
of_collapse_all ( ) → long | Folds every nested element (the root stays visible). A selection hidden by a fold moves onto the folded element, and ue_selection_changed says so. No ue_node_toggled: no gesture folds the whole tree at once. Returns 0, -2 when the component is not created |
of_clear ( ) → long | Empties the tree (like is_xml = ""); ib_wrap, ib_search_enabled, ib_find_match_case and ib_find_whole_word keep their values (of_reset is the one that puts every property back). Returns 0, -2 when the component is not created |
of_expand_to_level ( long al_level ) → long | Shows the tree down to al_level: elements at that depth or deeper fold shut (1 = the root's direct children, 0 folds the root). No ue_node_toggled; a selection it moves onto a folded element raises ue_selection_changed |
of_expand_path ( string as_path ) → long | Opens ONE element by its path — any XPath, like of_select_path — and the elements above it so it can be seen. Like its + marker, it raises ue_node_toggled for the element and for each folded element above it opened on the way (nothing for an element already open). Returns 0, -5 if no element with children matches, -2 if the component is not created |
of_collapse_path ( string as_path ) → long | Folds ONE element by its path (any XPath). Like its − marker, it raises ue_node_toggled when the element was open, and ue_selection_changed when the selection has to move onto it. Returns 0, -5 if no element with children matches, -2 if the component is not created |
of_is_expanded ( string as_path ) → boolean | true when the element at that path (any XPath) is open, read LIVE; false when it is folded, and for a node without children or a path that matches nothing. Enough to save what the user opened and restore it |
of_search ( string as_query ) → long | Highlights every occurrence (case-insensitive by default — see ib_find_match_case —, whole words only with ib_find_whole_word) and jumps to the first; only the elements that hide the CURRENT occurrence open, and of_clear_search folds them back. ue_search_result says how many. The search looks in the text as it is SHOWN: & is found as written. An empty query is of_clear_search. The search box opens with the query in it and the focus on it (the same as Ctrl+F): Enter moves to the next; with ib_search_enabled at false, the tree only highlights |
of_search_next ( ) → long | Moves to the NEXT match (wraps to the first after the last); ue_search_result reports the new position. Returns 0, or a negative code |
of_search_prev ( ) → long | Moves to the PREVIOUS match (wraps to the last before the first); ue_search_result reports the new position. Returns 0, or a negative code |
of_clear_search ( ) → long | Clears the search: no more highlight nor current match (of_match_count returns 0), the search box empties and closes, and the elements the search opened fold back as they were before it. Returns 0, or a negative code |
of_select_path ( string as_path ) → long | Selects and scrolls to the node at as_path; like the keyboard, it raises ue_selection_changed (nothing when the node is already selected); the folded elements that hide it open. as_path is ANY XPath 1.0 that designates a node of the tree: a path as the tree gives it (/order/@id), //line[@sku='A'], /order/lines/line[1], another prefix bound to the same namespace; the first node it matches is selected, and of_selected_path then gives the tree's own path. Returns 0, -5 when no node of the tree matches (the selection does not move), -2 when the component is not created |
of_selected_path ( ) → string | The path of the selected node, read LIVE: an XPath 1.0 location path to hand as it is to n_pbt_xml.of_get_value on the same document. EVERY line has its own: /order/lines/line[2] when a name repeats, /order/@id for an attribute, /p/text()[2] for a text, /order/comment()[1], /order/processing-instruction('x')[1], /comment()[1] before the root. An element in a DEFAULT namespace is written *[local-name()='Body'] — a bare name matches nothing in XPath; a prefixed name (soap:Body) is kept when its prefix designates the same namespace, otherwise the step names the namespace too (namespace-uri()). A closing tag gives its element. Empty when nothing is selected, and for the XML declaration or the DOCTYPE (not nodes) |
of_selected_value ( ) → string | The value of the selection, read LIVE and decoded — what n_pbt_xml.of_get_value reads at of_selected_path: an attribute's value, the text of a LEAF element (CDATA included, blanks kept), the text of a text line, a comment or a processing instruction. Empty for an element with children, or when nothing is selected |
of_selected_xml ( ) → string | The XML of the selected node, read LIVE: an element with everything it holds, an attribute as name="value", a text escaped, a comment, a CDATA or a processing instruction as written — what you copy from an XML editor. Empty when nothing is selected |
of_copy ( ) → long | Puts the XML of the selection on the clipboard, like Ctrl+C in the tree (the text of of_selected_xml). Returns 0, -4 if nothing is selected, -2 if the component is not created |
of_match_count ( ) → long | Returns how many OCCURRENCES the current search found (two on one line count two), read LIVE — the 12 of a 3 / 12 status line. 0 without a search |
of_match_index ( ) → long | Returns the 1-based position of the current match, read LIVE — the 3 of a 3 / 12 status line. 0 with no match |
Events #
| Event | When |
|---|---|
ue_node_clicked (string as_path) | The user clicked a node, or pressed Enter on a selected leaf: its XPath (/order/lines/line[2]); an attribute, a text, a comment or a processing instruction gives its own (/order/@id, /order/comment()[1]), a closing tag its element. Hand it to n_pbt_xml.of_get_value on the same document |
ue_node_toggled (string as_path, boolean ab_expanded) | An element was folded (ab_expanded = false) or opened (true): by the user (its + / − marker, the arrows, Enter or Space) or by of_expand_path / of_collapse_path. of_expand_all, of_collapse_all and of_expand_to_level do not raise it: no gesture folds the whole tree |
ue_selection_changed (string as_path) | The selection moved without a click, by the user or by your code: arrows, Home/End, Page Up/Down, of_select_path, or a fold that hides the selected line (the selection moves onto the folded element). Raised only when the selection really changes — a mouse click reports ue_node_clicked |
ue_search_result (long al_count, long al_index) | A search started or moved: al_count occurrences in all, the current one is al_index (1-based, 0 when none) — enough to show “3 / 12” |
ue_error (string as_message) | The text in is_xml is not valid XML: the message says where, in the display language (“Invalid XML : line 3, column 16 (…)”, the engine's own detail between brackets), and the tree shows the source around that line, the faulty one marked. Also raised when the document is too large to be shown |
Example #
Explore an API response #
// 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
Read the value of a clicked node #
// ue_node_clicked of uo_xml : the path is an XPath n_pbt_xml reads as it is
// (inv_xml is an n_pbt_xml created by the window, ipo_owner = the window)
inv_xml.of_load(/*xml*/ uo_xml.is_xml)
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()
Search whole words, case included #
// 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")
Good practice #
- It is a viewer, not an editor: it shows the XML, it does not change it. To read a value, hand the path from
ue_node_clickedton_pbt_xml.of_get_valueon the same text, or readof_selected_value. - A large XML stays smooth: only the lines on screen are drawn, an export of several thousand lines is browsed with the keyboard without waiting.
of_collapse_allfirst is still the most readable. - Invalid XML breaks nothing:
ue_errorsays so (with the line and the column of the fault, in the display language), and the tree shows the source around the faulty line. That is the feedback to show, not a crash. - A default namespace (
xmlns="urn:…", a SOAP response): the path is written*[local-name()='Body'], the only form an XPath without a registered prefix can read; a prefix declared again with another URI, or a sibling of the same name in another namespace, is written*[local-name()='x' and namespace-uri()='urn:…'].@xml:langreads as it is. Anxmlnsdeclaration is shown but has no path: XPath does not see it as an attribute. - What is shown is XML: an attribute value keeps its quotes and its encoded line breaks (
), a text its&and<and its significant blanks; only the layout line breaks around a text go. - With the keyboard: the arrows move from line to line, Right walks the attributes of a tag before going down, Page Down moves by one screen (a CDATA section of three hundred lines counts for its height), Ctrl+C copies the XML of the selection.
- Right to left: an XML document is a left-to-right text, the tree stays so in an RTL application (only the search box follows the application's direction).
Inherited from the common base #
These members exist on every visual component — they are not specific to this one. They are detailed once, in the transverse chapters; this table only says where to read them.
| Members | Role | Detailed in |
|---|---|---|
of_reset | Put the component back to zero | 3.6 Resetting a component: of_reset() |
of_register_shortcut · of_clear_shortcuts | The component's keyboard chords | 3.5 Keyboard shortcuts |
of_is_created · of_is_ready · of_get_last_error | Whether it was born, whether it is ready, what failed | 3.7 Diagnostics |
of_save_as_png · of_save_as_jpg | Export the rendering as an image | 3.8 Exporting the rendering as an image |
of_set_redraw | Group changes into a single repaint | 3.10 Best practices |
of_preload_icons | Icons shown with no delay | Instant display: of_icon |
of_set_translation | Translate one of the component's labels | 5.2 Adapting a label: of_set_translation |
of_focus_webview | Give the component the focus | 6.4 Keyboard and focus |
of_print · of_print_to_pdf | Print, or write a PDF | 6.9 Printing |
of_set_property · of_get_property · of_component_name | Driving a property by its name | 3.1 The property engine |