From 1c3de877f331e67551147f38bd1f37c6d819ceb8 Mon Sep 17 00:00:00 2001 From: Suero Date: Thu, 29 Feb 2024 18:30:38 -0300 Subject: [PATCH 1/6] feat(parser): adds CDATA nodes support --- addons/godot_xml/xml.gd | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/addons/godot_xml/xml.gd b/addons/godot_xml/xml.gd index 49e2932..3dcaed3 100644 --- a/addons/godot_xml/xml.gd +++ b/addons/godot_xml/xml.gd @@ -162,6 +162,11 @@ static func _make_node(queue: Array, parser: XMLParser): return _attach_node_data(queue.back(), parser) return + XMLParser.NODE_CDATA: + if queue.is_empty(): + return + _attach_node_name(queue.back(), parser) + return static func _make_node_element(parser: XMLParser): @@ -194,6 +199,9 @@ static func _attach_node_data(node: XMLNode, parser: XMLParser) -> void: # we therefore strip "blankets", resulting in only actual content slipping into .content node.content = parser.get_node_data().strip_edges().lstrip(" ").rstrip(" ") +static func _attach_node_name(node: XMLNode, parser: XMLParser) -> void: + if node.content.is_empty(): + node.content = parser.get_node_name().strip_edges().lstrip(" ").rstrip(" ") static func _get_attributes(parser: XMLParser) -> Dictionary: var attrs: Dictionary = {} From c3b76d6b70f897760638778f76ee5c09d3940f3c Mon Sep 17 00:00:00 2001 From: Suero Date: Sat, 2 Mar 2024 15:30:12 -0300 Subject: [PATCH 2/6] refactor: renames a function, adds cdata var to XMLNode, changes behaviour to cdata nodes --- addons/godot_xml/xml.gd | 8 +++++--- addons/godot_xml/xml_node.gd | 5 +++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/addons/godot_xml/xml.gd b/addons/godot_xml/xml.gd index 3dcaed3..9ca49e2 100644 --- a/addons/godot_xml/xml.gd +++ b/addons/godot_xml/xml.gd @@ -199,9 +199,11 @@ static func _attach_node_data(node: XMLNode, parser: XMLParser) -> void: # we therefore strip "blankets", resulting in only actual content slipping into .content node.content = parser.get_node_data().strip_edges().lstrip(" ").rstrip(" ") -static func _attach_node_name(node: XMLNode, parser: XMLParser) -> void: - if node.content.is_empty(): - node.content = parser.get_node_name().strip_edges().lstrip(" ").rstrip(" ") +static func _attach_node_cdata(node: XMLNode, parser: XMLParser) -> void: + # WARNING: The current implementation of XMLParser.get_node_name() does not raise an error for nodes of type NODE_CDATA. + # Instead, it returns the CDATA content. This behavior is undocumented and may change in future versions of Godot. + # It is recommended to open an issue on the Godot repository to address this inconsistency. + node.cdata.append(parser.get_node_name().strip_edges().lstrip(" ").rstrip(" ")) static func _get_attributes(parser: XMLParser) -> Dictionary: var attrs: Dictionary = {} diff --git a/addons/godot_xml/xml_node.gd b/addons/godot_xml/xml_node.gd index bba50a1..997c5af 100644 --- a/addons/godot_xml/xml_node.gd +++ b/addons/godot_xml/xml_node.gd @@ -11,6 +11,9 @@ var attributes: Dictionary = {} ## XML node content. var content: String = "" +## XML node CData. +var cdata: Array[String] = [] + ## Whether the XML node is an empty node (AKA standalone node). var standalone: bool = false @@ -23,6 +26,7 @@ var _node_props = null # Array[String] ## Converts this node (and all of it's children) into a [Dictionary]. ## Name is set as [code]__name__: name[/code]. ## Content is set as [code]__content__: content[/code]. +## CData is set as [code]__cdata__: cdata[/code]. ## Attributes are set as [code]attrs: {attr_name: attr_value}[/code]. ## Children are set as [code]children: {child_name: child_dict}[/code]. func to_dict() -> Dictionary: @@ -30,6 +34,7 @@ func to_dict() -> Dictionary: output["__name__"] = name output["__content__"] = content + output["__cdata__"] = cdata output["attrs"] = attributes var children_dict = {} From a54aaa9c957a7e1e331b771b5c4fab405b6132fd Mon Sep 17 00:00:00 2001 From: Suero Date: Sun, 3 Mar 2024 23:31:15 -0300 Subject: [PATCH 3/6] fix: fixes typos and code errors --- addons/godot_xml/xml.gd | 2 +- addons/godot_xml/xml_node.gd | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/godot_xml/xml.gd b/addons/godot_xml/xml.gd index 9ca49e2..e622914 100644 --- a/addons/godot_xml/xml.gd +++ b/addons/godot_xml/xml.gd @@ -165,7 +165,7 @@ static func _make_node(queue: Array, parser: XMLParser): XMLParser.NODE_CDATA: if queue.is_empty(): return - _attach_node_name(queue.back(), parser) + _attach_node_cdata(queue.back(), parser) return diff --git a/addons/godot_xml/xml_node.gd b/addons/godot_xml/xml_node.gd index 997c5af..a19c282 100644 --- a/addons/godot_xml/xml_node.gd +++ b/addons/godot_xml/xml_node.gd @@ -11,7 +11,7 @@ var attributes: Dictionary = {} ## XML node content. var content: String = "" -## XML node CData. +## XML node CDATA. var cdata: Array[String] = [] ## Whether the XML node is an empty node (AKA standalone node). @@ -26,7 +26,7 @@ var _node_props = null # Array[String] ## Converts this node (and all of it's children) into a [Dictionary]. ## Name is set as [code]__name__: name[/code]. ## Content is set as [code]__content__: content[/code]. -## CData is set as [code]__cdata__: cdata[/code]. +## CDATA is set as [code]__cdata__: [cdata, ...][/code]. ## Attributes are set as [code]attrs: {attr_name: attr_value}[/code]. ## Children are set as [code]children: {child_name: child_dict}[/code]. func to_dict() -> Dictionary: From e9bd12ba1c2d0755dfd18f8bf62b7c0d8bd8a516 Mon Sep 17 00:00:00 2001 From: Suero Date: Sun, 3 Mar 2024 23:36:37 -0300 Subject: [PATCH 4/6] feat(dumper): adds cnode support to the dumper --- addons/godot_xml/xml_node.gd | 64 ++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/addons/godot_xml/xml_node.gd b/addons/godot_xml/xml_node.gd index a19c282..e9b15bb 100644 --- a/addons/godot_xml/xml_node.gd +++ b/addons/godot_xml/xml_node.gd @@ -103,13 +103,13 @@ func _initialize_node_properties(): func _dump() -> String: var template = ( - "<{node_name}{attributes}>{content}{children}" + "<{node_name}{attributes}>{content}{children}{cdata_nodes}" if not standalone else "<{node_name}{attributes}/>" ) var attribute_string = "" var children_string = "" - + var cdata_nodes = "" if not attributes.is_empty(): attribute_string += " " @@ -120,41 +120,49 @@ func _dump() -> String: for child in children: children_string += child._dump() + for cdata_content in cdata: + cdata_nodes += cdata_content + return template.format({ "node_name": name, "attributes": attribute_string, "content": content, "children": children_string, + "cdata_nodes": cdata_nodes, }) func _dump_pretty(indent_level: int, indent_length: int) -> String: - var template = ( - "{indent}<{node_name}{attributes}>{content}{children}\n{indent}" - if not standalone else - "{indent}<{node_name}{attributes}/>" - ) - var indent_string = " ".repeat(indent_level * indent_length) - var indent_next_string = indent_string + " ".repeat(indent_length) - var attribute_string = "" - var content_string = "\n" + indent_next_string + content if not content.is_empty() else "" - var children_string = "" - - if not attributes.is_empty(): - attribute_string += " " - - for attribute_key in attributes: - var attribute_value = attributes.get(attribute_key) - attribute_string += '{key}="{value}"'.format({"key": attribute_key, "value": attribute_value}) + var template = ( + "{indent}<{node_name}{attributes}>{content}{children}{cdata_nodes}\n{indent}" + if not standalone else + "{indent}<{node_name}{attributes}/>" + ) + var indent_string = " ".repeat(indent_level * indent_length) + var indent_next_string = indent_string + " ".repeat(indent_length) + var attribute_string = "" + var content_string = "\n" + indent_next_string + content if not content.is_empty() else "" + var children_string = "" + var cdata_nodes = "" + + if not attributes.is_empty(): + attribute_string += " " + + for attribute_key in attributes: + var attribute_value = attributes.get(attribute_key) + attribute_string += '{key}="{value}"'.format({"key": attribute_key, "value": attribute_value}) - for child in children: - children_string += "\n" + child._dump_pretty(indent_level + 1, indent_length) + for child in children: + children_string += "\n" + child._dump_pretty(indent_level + 1, indent_length) - return template.format({ - "node_name": name, - "attributes": attribute_string, - "content": content_string, - "children": children_string, + for cdata_content in cdata: + cdata_nodes += "\n" + indent_next_string + cdata_content - "indent": indent_string, - }) + return template.format({ + "node_name": name, + "attributes": attribute_string, + "content": content_string, + "children": children_string, + "cdata_nodes": cdata_nodes, + "indent": indent_string, + }) From b434d559b2a36b529f53e8a532f93760a8041cf5 Mon Sep 17 00:00:00 2001 From: elenakrittik Date: Mon, 4 Mar 2024 19:53:26 +0300 Subject: [PATCH 5/6] refactor: Include CDATA in repr, fix dotted access for .cdata, fix CDATA dumping as regular content, reorder and rename a few things. --- addons/godot_xml/xml_node.gd | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/addons/godot_xml/xml_node.gd b/addons/godot_xml/xml_node.gd index e9b15bb..5548606 100644 --- a/addons/godot_xml/xml_node.gd +++ b/addons/godot_xml/xml_node.gd @@ -47,10 +47,11 @@ func to_dict() -> Dictionary: func _to_string(): - return "" % [ + return "" % [ name, "{...}" if len(attributes) > 0 else "{}", '"..."' if len(content) > 0 else '""', + "[...]" if len(cdata) > 0 else "[]", str(standalone), "[...]" if len(children) > 0 else "[]" ] @@ -61,7 +62,7 @@ func _get(property: StringName): if _node_props == null: _initialize_node_properties() - if property not in ["name", "attributes", "content", "standalone", "children"] and property in _node_props: + if property not in ["name", "attributes", "content", "cdata", "standalone", "children"] and property in _node_props: for child in children: if child.name == property: return child @@ -103,13 +104,14 @@ func _initialize_node_properties(): func _dump() -> String: var template = ( - "<{node_name}{attributes}>{content}{children}{cdata_nodes}" + "<{node_name}{attributes}>{content}{cdata}{children}" if not standalone else "<{node_name}{attributes}/>" ) var attribute_string = "" var children_string = "" - var cdata_nodes = "" + var cdata_string = "" + if not attributes.is_empty(): attribute_string += " " @@ -121,20 +123,20 @@ func _dump() -> String: children_string += child._dump() for cdata_content in cdata: - cdata_nodes += cdata_content + cdata_string += "" % cdata_content return template.format({ "node_name": name, "attributes": attribute_string, "content": content, + "cdata": cdata_string, "children": children_string, - "cdata_nodes": cdata_nodes, }) func _dump_pretty(indent_level: int, indent_length: int) -> String: var template = ( - "{indent}<{node_name}{attributes}>{content}{children}{cdata_nodes}\n{indent}" + "{indent}<{node_name}{attributes}>{content}{cdata}{children}\n{indent}" if not standalone else "{indent}<{node_name}{attributes}/>" ) @@ -143,7 +145,7 @@ func _dump_pretty(indent_level: int, indent_length: int) -> String: var attribute_string = "" var content_string = "\n" + indent_next_string + content if not content.is_empty() else "" var children_string = "" - var cdata_nodes = "" + var cdata_string = "" if not attributes.is_empty(): attribute_string += " " @@ -156,13 +158,13 @@ func _dump_pretty(indent_level: int, indent_length: int) -> String: children_string += "\n" + child._dump_pretty(indent_level + 1, indent_length) for cdata_content in cdata: - cdata_nodes += "\n" + indent_next_string + cdata_content + cdata_string += "\n" + indent_next_string + ("" % cdata_content) return template.format({ "node_name": name, "attributes": attribute_string, "content": content_string, + "cdata": cdata_string, "children": children_string, - "cdata_nodes": cdata_nodes, "indent": indent_string, }) From 4da9016a63b449c7cdc74054034be5f5b53cf95a Mon Sep 17 00:00:00 2001 From: elenakrittik Date: Mon, 4 Mar 2024 22:38:58 +0300 Subject: [PATCH 6/6] misc: Remove TODO note --- addons/godot_xml/xml.gd | 3 --- 1 file changed, 3 deletions(-) diff --git a/addons/godot_xml/xml.gd b/addons/godot_xml/xml.gd index e622914..1a0d430 100644 --- a/addons/godot_xml/xml.gd +++ b/addons/godot_xml/xml.gd @@ -200,9 +200,6 @@ static func _attach_node_data(node: XMLNode, parser: XMLParser) -> void: node.content = parser.get_node_data().strip_edges().lstrip(" ").rstrip(" ") static func _attach_node_cdata(node: XMLNode, parser: XMLParser) -> void: - # WARNING: The current implementation of XMLParser.get_node_name() does not raise an error for nodes of type NODE_CDATA. - # Instead, it returns the CDATA content. This behavior is undocumented and may change in future versions of Godot. - # It is recommended to open an issue on the Godot repository to address this inconsistency. node.cdata.append(parser.get_node_name().strip_edges().lstrip(" ").rstrip(" ")) static func _get_attributes(parser: XMLParser) -> Dictionary: