diff --git a/nemubot/tools/test_xmlparser.py b/nemubot/tools/test_xmlparser.py
index d7f5a9a..0feda73 100644
--- a/nemubot/tools/test_xmlparser.py
+++ b/nemubot/tools/test_xmlparser.py
@@ -1,5 +1,6 @@
import unittest
+import io
import xml.parsers.expat
from nemubot.tools.xmlparser import XMLParser
@@ -12,6 +13,11 @@ class StringNode():
def characters(self, content):
self.string += content
+ def saveElement(self, store, tag="string"):
+ store.startElement(tag, {})
+ store.characters(self.string)
+ store.endElement(tag)
+
class TestNode():
def __init__(self, option=None):
@@ -22,6 +28,15 @@ class TestNode():
self.mystr = child.string
return True
+ def saveElement(self, store, tag="test"):
+ store.startElement(tag, {"option": self.option})
+
+ strNode = StringNode()
+ strNode.string = self.mystr
+ strNode.saveElement(store)
+
+ store.endElement(tag)
+
class Test2Node():
def __init__(self, option=None):
@@ -33,6 +48,15 @@ class Test2Node():
self.mystrs.append(attrs["value"])
return True
+ def saveElement(self, store, tag="test"):
+ store.startElement(tag, {"option": self.option} if self.option is not None else {})
+
+ for mystr in self.mystrs:
+ store.startElement("string", {"value": mystr})
+ store.endElement("string")
+
+ store.endElement(tag)
+
class TestXMLParser(unittest.TestCase):
@@ -44,9 +68,11 @@ class TestXMLParser(unittest.TestCase):
p.CharacterDataHandler = mod.characters
p.EndElementHandler = mod.endElement
- p.Parse("toto", 1)
+ inputstr = "toto"
+ p.Parse(inputstr, 1)
self.assertEqual(mod.root.string, "toto")
+ self.assertEqual(mod.saveDocument(header=False).getvalue(), inputstr)
def test_parser2(self):
@@ -57,10 +83,12 @@ class TestXMLParser(unittest.TestCase):
p.CharacterDataHandler = mod.characters
p.EndElementHandler = mod.endElement
- p.Parse("toto", 1)
+ inputstr = 'toto'
+ p.Parse(inputstr, 1)
self.assertEqual(mod.root.option, "123")
self.assertEqual(mod.root.mystr, "toto")
+ self.assertEqual(mod.saveDocument(header=False).getvalue(), inputstr)
def test_parser3(self):
@@ -71,12 +99,14 @@ class TestXMLParser(unittest.TestCase):
p.CharacterDataHandler = mod.characters
p.EndElementHandler = mod.endElement
- p.Parse("", 1)
+ inputstr = ''
+ p.Parse(inputstr, 1)
self.assertEqual(mod.root.option, None)
self.assertEqual(len(mod.root.mystrs), 2)
self.assertEqual(mod.root.mystrs[0], "toto")
self.assertEqual(mod.root.mystrs[1], "toto2")
+ self.assertEqual(mod.saveDocument(header=False, short_empty_elements=True).getvalue(), inputstr)
if __name__ == '__main__':
diff --git a/nemubot/tools/xmlparser/__init__.py b/nemubot/tools/xmlparser/__init__.py
index abc5bb9..c8d393a 100644
--- a/nemubot/tools/xmlparser/__init__.py
+++ b/nemubot/tools/xmlparser/__init__.py
@@ -134,6 +134,21 @@ class XMLParser:
return
raise TypeError(name + " tag not expected in " + self.display_stack())
+ def saveDocument(self, f=None, header=True, short_empty_elements=False):
+ if f is None:
+ import io
+ f = io.StringIO()
+
+ import xml.sax.saxutils
+ gen = xml.sax.saxutils.XMLGenerator(f, "utf-8", short_empty_elements=short_empty_elements)
+ if header:
+ gen.startDocument()
+ self.root.saveElement(gen)
+ if header:
+ gen.endDocument()
+
+ return f
+
def parse_file(filename):
p = xml.parsers.expat.ParserCreate()
diff --git a/nemubot/tools/xmlparser/basic.py b/nemubot/tools/xmlparser/basic.py
index 8456629..f2d9fd5 100644
--- a/nemubot/tools/xmlparser/basic.py
+++ b/nemubot/tools/xmlparser/basic.py
@@ -44,6 +44,13 @@ class ListNode:
return self.items.__repr__()
+ def saveElement(self, store, tag="list"):
+ store.startElement(tag, {})
+ for i in self.items:
+ i.saveElement(store)
+ store.endElement(tag)
+
+
class DictNode:
"""XML node representing a Python dictionnnary
@@ -106,3 +113,10 @@ class DictNode:
def __repr__(self):
return self.items.__repr__()
+
+
+ def saveElement(self, store, tag="dict"):
+ store.startElement(tag, {})
+ for k, v in self.items.items():
+ v.saveElement(store)
+ store.endElement(tag)
diff --git a/nemubot/tools/xmlparser/genericnode.py b/nemubot/tools/xmlparser/genericnode.py
index 9c29a23..425934c 100644
--- a/nemubot/tools/xmlparser/genericnode.py
+++ b/nemubot/tools/xmlparser/genericnode.py
@@ -53,6 +53,14 @@ class ParsingNode:
return item in self.attrs
+ def saveElement(self, store, tag=None):
+ store.startElement(tag if tag is not None else self.tag, self.attrs)
+ for child in self.children:
+ child.saveElement(store)
+ store.characters(self.content)
+ store.endElement(tag if tag is not None else self.tag)
+
+
class GenericNode(ParsingNode):
"""Consider all subtags as dictionnary