tools/xmlparser: implement writer
This commit is contained in:
parent
7eac685a0a
commit
c8afa65dcb
|
@ -1,5 +1,6 @@
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
import io
|
||||||
import xml.parsers.expat
|
import xml.parsers.expat
|
||||||
|
|
||||||
from nemubot.tools.xmlparser import XMLParser
|
from nemubot.tools.xmlparser import XMLParser
|
||||||
|
@ -12,6 +13,11 @@ class StringNode():
|
||||||
def characters(self, content):
|
def characters(self, content):
|
||||||
self.string += content
|
self.string += content
|
||||||
|
|
||||||
|
def saveElement(self, store, tag="string"):
|
||||||
|
store.startElement(tag, {})
|
||||||
|
store.characters(self.string)
|
||||||
|
store.endElement(tag)
|
||||||
|
|
||||||
|
|
||||||
class TestNode():
|
class TestNode():
|
||||||
def __init__(self, option=None):
|
def __init__(self, option=None):
|
||||||
|
@ -22,6 +28,15 @@ class TestNode():
|
||||||
self.mystr = child.string
|
self.mystr = child.string
|
||||||
return True
|
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():
|
class Test2Node():
|
||||||
def __init__(self, option=None):
|
def __init__(self, option=None):
|
||||||
|
@ -33,6 +48,15 @@ class Test2Node():
|
||||||
self.mystrs.append(attrs["value"])
|
self.mystrs.append(attrs["value"])
|
||||||
return True
|
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):
|
class TestXMLParser(unittest.TestCase):
|
||||||
|
|
||||||
|
@ -44,9 +68,11 @@ class TestXMLParser(unittest.TestCase):
|
||||||
p.CharacterDataHandler = mod.characters
|
p.CharacterDataHandler = mod.characters
|
||||||
p.EndElementHandler = mod.endElement
|
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.root.string, "toto")
|
||||||
|
self.assertEqual(mod.saveDocument(header=False).getvalue(), inputstr)
|
||||||
|
|
||||||
|
|
||||||
def test_parser2(self):
|
def test_parser2(self):
|
||||||
|
@ -57,10 +83,12 @@ class TestXMLParser(unittest.TestCase):
|
||||||
p.CharacterDataHandler = mod.characters
|
p.CharacterDataHandler = mod.characters
|
||||||
p.EndElementHandler = mod.endElement
|
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.option, "123")
|
||||||
self.assertEqual(mod.root.mystr, "toto")
|
self.assertEqual(mod.root.mystr, "toto")
|
||||||
|
self.assertEqual(mod.saveDocument(header=False).getvalue(), inputstr)
|
||||||
|
|
||||||
|
|
||||||
def test_parser3(self):
|
def test_parser3(self):
|
||||||
|
@ -71,12 +99,14 @@ class TestXMLParser(unittest.TestCase):
|
||||||
p.CharacterDataHandler = mod.characters
|
p.CharacterDataHandler = mod.characters
|
||||||
p.EndElementHandler = mod.endElement
|
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(mod.root.option, None)
|
||||||
self.assertEqual(len(mod.root.mystrs), 2)
|
self.assertEqual(len(mod.root.mystrs), 2)
|
||||||
self.assertEqual(mod.root.mystrs[0], "toto")
|
self.assertEqual(mod.root.mystrs[0], "toto")
|
||||||
self.assertEqual(mod.root.mystrs[1], "toto2")
|
self.assertEqual(mod.root.mystrs[1], "toto2")
|
||||||
|
self.assertEqual(mod.saveDocument(header=False, short_empty_elements=True).getvalue(), inputstr)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -134,6 +134,21 @@ class XMLParser:
|
||||||
return
|
return
|
||||||
raise TypeError(name + " tag not expected in " + self.display_stack())
|
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):
|
def parse_file(filename):
|
||||||
p = xml.parsers.expat.ParserCreate()
|
p = xml.parsers.expat.ParserCreate()
|
||||||
|
|
|
@ -44,6 +44,13 @@ class ListNode:
|
||||||
return self.items.__repr__()
|
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:
|
class DictNode:
|
||||||
|
|
||||||
"""XML node representing a Python dictionnnary
|
"""XML node representing a Python dictionnnary
|
||||||
|
@ -106,3 +113,10 @@ class DictNode:
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self.items.__repr__()
|
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)
|
||||||
|
|
|
@ -53,6 +53,14 @@ class ParsingNode:
|
||||||
return item in self.attrs
|
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):
|
class GenericNode(ParsingNode):
|
||||||
|
|
||||||
"""Consider all subtags as dictionnary
|
"""Consider all subtags as dictionnary
|
||||||
|
|
Loading…
Reference in New Issue
Block a user