Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions base/src/xml.act
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,30 @@ n.text and c.tail for all children of n.
def encode(self) -> str:
NotImplemented

def __str__(self):
return self.encode()

def __repr__(self):
# Build the arguments to xml.Node() and skip arguments where our value
# equals the default. We do this with appending to a string because that
# does not leak the *mut* effect, unlike appending to a list.
args = repr(self.tag)
if len(self.nsdefs) != 0:
args += ", nsdefs={repr(self.nsdefs)}"
if self.prefix is not None:
args += ", prefix={repr(self.prefix)}"
if len(self.attributes) != 0:
args += ", attributes={repr(self.attributes)}"
if len(self.children) != 0:
args += ", children={repr(self.children)}"
if self.text is not None:
args += ", text={repr(self.text)}"
if self.tail is not None:
args += ", tail={repr(self.tail)}"

return "xml.Node({args})"


class XmlParseError(ValueError):
"""Exception raised for XML parsing errors

Expand Down
7 changes: 4 additions & 3 deletions base/src/xml.ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,14 @@ static unsigned char* copy_with_xml_escape(unsigned char *dst, B_str src, int es
}

// Helper function to collect text from consecutive TEXT and CDATA nodes
// Returns the combined string and updates the node pointer to the first non-text node
// Returns the combined string (or NULL if there is no text/CDATA content) and
// updates the node pointer to the first non-text node
// Note: cur_ptr is passed by reference (pointer to pointer) so we can update the caller's pointer
// to skip past all consumed text/CDATA nodes
static B_str collect_text_cdata_nodes(xmlNodePtr *cur_ptr) {
xmlNodePtr cur = *cur_ptr;
if (!cur || (cur->type != XML_TEXT_NODE && cur->type != XML_CDATA_SECTION_NODE)) {
return to$str("");
return NULL;
}

// Count total length of combined text and CDATA nodes
Expand Down Expand Up @@ -106,7 +107,7 @@ static B_str collect_text_cdata_nodes(xmlNodePtr *cur_ptr) {
}

*cur_ptr = cur;
return to$str("");
return NULL;
}

xmlQ_Node $NodePtr2Node(xmlNodePtr node) {
Expand Down
5 changes: 5 additions & 0 deletions test/stdlib_tests/src/test_xml.act
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,8 @@ def _test_xml_namespace_attributes_undefined():
testing.assertEqual(child_attr.1, 'child', "Undefined namespace: child attribute value not preserved")
e = xml.encode(d)
testing.assertEqual(e, test_xml, "Undefined namespace: roundtrip failed")

def _test_xml_repr():
test_xml = """<data xmlns="http://default"><a xmlns:ns="http://foo" ns:operation="remove"><ns:b ns:type="element">text</ns:b></a></data>"""
d = xml.decode(test_xml)
testing.assertEqual(repr(d), "xml.Node(tag='data', nsdefs=[(None, 'http://default')], children=[xml.Node(tag='a', nsdefs=[('ns', 'http://foo')], attributes=[('ns:operation', 'remove')], children=[xml.Node(tag='b', prefix='ns', attributes=[('ns:type', 'element')], text='text')])])")
Loading