aboutsummaryrefslogtreecommitdiff
path: root/rpki/xml_utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'rpki/xml_utils.py')
-rw-r--r--rpki/xml_utils.py75
1 files changed, 69 insertions, 6 deletions
diff --git a/rpki/xml_utils.py b/rpki/xml_utils.py
index 9b443d0b..99377e17 100644
--- a/rpki/xml_utils.py
+++ b/rpki/xml_utils.py
@@ -56,6 +56,8 @@ class sax_handler(xml.sax.handler.ContentHandler):
many XML namespace games.
"""
+ # .pdu, .name, and .version are provided by subclass
+
def __init__(self):
"""
Initialize SAX handler.
@@ -145,8 +147,7 @@ class sax_handler(xml.sax.handler.ContentHandler):
class base_elt(object):
"""
Virtual base class for XML message elements. The left-right and
- publication protocols use this. At least for now, the up-down
- protocol does not, due to different design assumptions.
+ publication_control protocols use this.
"""
## @var attributes
@@ -161,6 +162,10 @@ class base_elt(object):
# Boolean attributes (value "yes" or "no") for this element.
booleans = ()
+ ## @var text_attribute
+ # Name of class attribute that tells us where to put text values, if any.
+ text_attribute = None
+
def startElement(self, stack, name, attrs):
"""
Default startElement() handler: just process attributes.
@@ -178,6 +183,47 @@ class base_elt(object):
assert name == self.element_name, "Unexpected name %s, stack %s" % (name, stack)
stack.pop()
+ @classmethod
+ def fromXML(cls, elt):
+ """
+ First cut at non-SAX message unpacker. This will probably change.
+ """
+
+ logger.warning("base_elt(): Element %r (len %s)", elt, len(elt))
+
+ self = cls()
+
+ for key in self.attributes:
+ val = elt.get(key, None)
+ if val is not None:
+ val = val.encode("ascii")
+ if val.isdigit() and not key.endswith("_handle"):
+ val = long(val)
+ setattr(self, key, val)
+ for key in self.booleans:
+ setattr(self, key, elt.get(key, False))
+
+ # This test could go in an extended method in text_elt. Then
+ # again, perhaps spreading the logic in as many places as we
+ # possibly can is not really helping matters....
+
+ if self.text_attribute is not None:
+ setattr(self, self.text_attribute, elt.text)
+
+ # In the long run, we probably want the key for that to include
+ # the namespace, but that would break the current .toXML() code,
+ # so kludge it for now.
+
+ for b64 in elt:
+ # XXX
+ logger.warning("base_elt(): XML tag %r, XML namespace %r", b64.tag, self.xmlns)
+ assert b64.tag.startswith(self.xmlns)
+ ename = b64.tag[len(self.xmlns):]
+ etype = self.elements[ename]
+ setattr(self, ename, etype(Base64 = b64.text))
+
+ return self
+
def toXML(self):
"""
Default toXML() element generator.
@@ -246,10 +292,6 @@ class text_elt(base_elt):
Virtual base class for XML message elements that contain text.
"""
- ## @var text_attribute
- # Name of the class attribute that holds the text value.
- text_attribute = None
-
def endElement(self, stack, name, text):
"""
Extract text from parsed XML.
@@ -530,3 +572,24 @@ class msg(list):
"""
return self.type == "reply"
+
+ @classmethod
+ def fromXML(cls, elt):
+ """
+ First cut at non-SAX message unpacker. This will probably change.
+ """
+
+ assert cls.version == int(elt.get("version"))
+ self = cls()
+ self.type = elt.get("type")
+
+ # This could be simplified by including the namespace name in the .pdus[] key.
+
+ for sub in elt:
+ # XXX
+ logger.warning("msg(): XML tag %r, XML namespace %r", sub.tag, self.xmlns)
+ assert sub.tag.startswith(self.xmlns)
+ self.append(self.pdus[sub.tag[len(self.xmlns):]].fromXML(sub))
+
+ logger.warning("msg(): parsed %r", self)
+ return self