Linting, XML to_table and fix JSON viz for XML (#10554)

- Linting fixes.
- `XML_Document` and `XML_Element` have `to_table` method.
- Add `to_default_visualization_data` to `XML_Document` and `XML_Element`.
- Add support to Table viz to render.

![image](https://github.com/user-attachments/assets/f01a3508-443e-48db-ad4f-605094a04c2b)

![image](https://github.com/user-attachments/assets/c7573b68-7549-494f-9c59-ea240178c0eb)
This commit is contained in:
James Dunkerley 2024-07-15 19:33:37 +01:00 committed by GitHub
parent 11d2a44792
commit cc1ac87c99
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 89 additions and 6 deletions

View File

@ -21,6 +21,7 @@ type Map key value
Error.throw (Deprecated.Warning "Standard.Base.Data.Map.Map" "singleton" "Deprecated: `Map.singleton` has been replaced by `Dictionary.singleton`.")
## PRIVATE
GROUP Constants
ICON convert
DEPRECATED Use Dictionary.from_keys_and_values instead.
from_keys_and_values : Vector Any -> Vector Any -> Boolean -> Any ! Deprecated
@ -29,6 +30,7 @@ type Map key value
Error.throw (Deprecated.Warning "Standard.Base.Data.Map.Map" "from_keys_and_values" "Deprecated: `Map.from_keys_and_values` has been replaced by `Dictionary.from_keys_and_values`.")
## PRIVATE
GROUP Constants
ICON convert
DEPRECATED Use Dictionary.from_vector instead.
from_vector : Vector Any -> Boolean -> Any ! Deprecated

View File

@ -1103,7 +1103,7 @@ Text.take self range:(Text_Sub_Range | Index_Sub_Range | Range | Integer)=..Firs
"Hello World!".drop (..By_Index [Range 0 3, 6, Range 6 12 2]) == "lo ol!"
"Hello World!".drop (..Sample 3 seed=42) == "HeloWorl!"
@range Text_Sub_Range.default_widget
Text.drop : (Text_Sub_Range | Index_Sub_Range | Range) -> Text ! Index_Out_Of_Bounds
Text.drop : (Text_Sub_Range | Index_Sub_Range | Range | Integer) -> Text ! Index_Out_Of_Bounds
Text.drop self range:(Text_Sub_Range | Index_Sub_Range | Range | Integer)=..First =
ranges = Codepoint_Ranges.resolve self range
case ranges of

View File

@ -24,8 +24,8 @@ import project.Nothing.Nothing
import project.Panic.Panic
import project.Warning.Warning
from project.Data.Boolean import Boolean, False, True
from project.Data.Time.Date import make_day_picker
from project.Data.Text.Extensions import all
from project.Data.Time.Date import make_day_picker
from project.Metadata import Display, Widget
from project.Widget_Helpers import make_date_time_format_selector

View File

@ -369,6 +369,16 @@ type XML_Document
to_display_text : Text
to_display_text self = "XML_Document (" + self.root_element.to_display_text + ")"
## PRIVATE
Transform the XML document into text for displaying as part of its
default visualization.
to_default_visualization_data : Text
to_default_visualization_data self =
outer_vec = Vector.build initial_capacity=2 builder->
builder.append ["type", "XML_Document"]
builder.append ["root_element", self.root_element.to_default_visualization_data as_js_object=True]
JS_Object.from_pairs outer_vec . to_json
type XML_Element
## GROUP Metadata
ICON metadata
@ -673,7 +683,28 @@ type XML_Element
new java_element = XML_Element.Value java_element (build_child_list java_element)
## PRIVATE
Value (java_element:Element) (~children_cache:(Vector (XML_Element | Text)))
private Value (java_element:Element) (~children_cache:(Vector (XML_Element | Text)))
## PRIVATE
Transform the vector into text for displaying as part of its default
visualization.
to_default_visualization_data : Boolean -> Boolean -> Text | JS_Object
to_default_visualization_data self nested:Boolean=False as_js_object:Boolean=False =
vec = Vector.build initial_capacity=4 builder->
builder.append ["type", "XML_Element"]
builder.append ["tag", self.name]
if self.attributes.length > 0 then builder.append ["attributes", self.attributes.to_js_object]
if self.children_cache.length > 0 then
inner_render = if nested then _.to_display_text else
c-> case c of
_ : XML_Element -> c.to_default_visualization_data nested=True as_js_object=True
_ -> c
## Limit to 50 children to avoid excessive rendering.
builder.append ["children", self.children_cache.take 50 . map inner_render + (if self.children_cache.length > 50 then ["..."] else [])]
builder.append ["children_count", self.children_cache.length]
js_object = JS_Object.from_pairs vec
if as_js_object then js_object else js_object.to_json
type XML_Error
## An error that indicates that the XML data could not be parsed.

View File

@ -10,8 +10,8 @@ import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
import Standard.Base.Errors.Illegal_State.Illegal_State
import Standard.Base.Internal.Polyglot_Helpers
import Standard.Base.Internal.Rounding_Helpers
from Standard.Base.Metadata.Widget import Numeric_Input
from Standard.Base.Data.Index_Sub_Range import drop_helper, normalize_ranges, take_helper
from Standard.Base.Metadata.Widget import Numeric_Input
from Standard.Base.Widget_Helpers import make_data_cleanse_vector_selector, make_format_chooser, make_regex_text_widget
import project.Constants.Previous_Value

View File

@ -57,6 +57,20 @@ JS_Object.to_table : Vector | Nothing -> Table ! Type_Error
JS_Object.to_table self fields=Nothing =
self.to Table fields
## GROUP Standard.Base.Conversions
ICON convert
Converts this `XML_Document` into a `Table`.
XML_Document.to_table : Table ! Type_Error
XML_Document.to_table self =
self.to Table
## GROUP Standard.Base.Conversions
ICON convert
Converts this `XML_Document` into a `Table`.
XML_Element.to_table : Table ! Type_Error
XML_Element.to_table self =
self.to Table
## GROUP Standard.Base.Constants
ICON data_input
Converts an object or a Vector of object into a Table, by looking up the

View File

@ -49,8 +49,9 @@ prepare_visualization y max_rows=1000 =
_ : Excel_Workbook ->
js_value = x.to_js_object
JS_Object.from_pairs [["json", js_value], ["sheet_names", x . sheet_names], ["type", "Excel_Workbook"]]
_ ->
make_json_for_other x
_ : XML_Document -> make_json_for_xml_element x.root_element max_rows "XML_Document"
_ : XML_Element -> make_json_for_xml_element x max_rows
_ -> make_json_for_other x
result.to_text
@ -137,6 +138,28 @@ make_json_for_js_object js_object max_items =
data = ["data", [mapped.map .first, mapped.map .second]]
JS_Object.from_pairs [header, data, all_rows, ["type", "Map"]]
## PRIVATE
Render XML_Element to JSON
make_json_for_xml_element : XML_Element -> Integer -> Text -> JS_Object
make_json_for_xml_element xml_element max_items type:Text="XML_Element" =
header = ["header", ["key", "type", "value"]]
all_rows = ["all_rows_count", xml_element.attributes.length + xml_element.children.length]
attribs = xml_element.attributes.to_vector.take max_items . map a-> ["@" + a.first, "Attribute", a.second]
children = xml_element.children.take (max_items - attribs.length) . map_with_index i->c-> if c.is_a Text then [i.to_text, "Text", c] else
render_start = "<"+c.name
render_attribs = if c.attributes.length == 0 then "" else
" " + ((c.attributes.to_vector.take 5 . map a-> a.first+'="'+a.second+'"') . join " ") + (if c.attributes.length > 5 then " ..." else "")
render_end = case c.child_count of
0 -> "/>"
1 -> if c.children.first.is_a Text then ">" + c.children.first + "</"+c.name+">" else "> ... 1 child element ... </"+c.name+">"
_ -> ">..." + c.child_count.to_text + " child elements...</"+c.name+">"
[i.to_text, "Element", render_start+render_attribs+render_end]
map_vector = Warning.clear (attribs + children)
data = ["data", [map_vector.map .first, map_vector.map .second, map_vector.map i-> i.at 2]]
JS_Object.from_pairs [header, data, all_rows, ["type", type]]
## PRIVATE
Creates a JSON representation for the visualizations.

View File

@ -399,6 +399,19 @@ add_specs suite_builder =
t.at "Children" . at 0 . at 4 . name . should_equal "Magazine"
t.column_names . should_not_contain "Value"
group_builder.specify "Can convert XML_Document and XML_Element to a table using to_table" <|
[data.library_document, data.library_root].map x->
t = x.to_table
t.at "Name" . to_vector . should_equal ["Library"]
t.at "@catalog" . to_vector . should_equal ["Fiction"]
t.at "@letter" . to_vector . should_equal ["A"]
t.at "Children" . at 0 . at 0 . trim . should_equal "Hello"
t.at "Children" . at 0 . at 1 . name . should_equal "Book"
t.at "Children" . at 0 . at 2 . trim . should_equal "World"
t.at "Children" . at 0 . at 3 . name . should_equal "Book"
t.at "Children" . at 0 . at 4 . name . should_equal "Magazine"
t.column_names . should_not_contain "Value"
group_builder.specify "Can expand the Children column to rows" <|
t = data.library_root.to Table . expand_to_rows "Children"
t.at "Name" . to_vector . should_equal (Vector.fill 5 "Library")