1
0
Fork 0

tools/xmlparser: implement writer

This commit is contained in:
nemunaire 2017-07-27 20:44:26 +02:00
parent f16dedb320
commit 39056cf358
4 changed files with 76 additions and 3 deletions

View File

@ -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("<string>toto</string>", 1)
inputstr = "<string>toto</string>"
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("<test option='123'><string>toto</string></test>", 1)
inputstr = '<test option="123"><string>toto</string></test>'
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("<test><string value='toto' /><string value='toto2' /></test>", 1)
inputstr = '<test><string value="toto"/><string value="toto2"/></test>'
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__':

View File

@ -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()

View File

@ -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,16 @@ 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():
store.startElement("item", {"key": k})
if isinstance(v, str):
store.characters(v)
else:
for i in v:
i.saveElement(store)
store.endElement("item")
store.endElement(tag)

View File

@ -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