diff MoinMoin/wikixml/marshal.py @ 0:77665d8e2254

tag of nonpublic@localhost--archive/moin--enterprise--1.5--base-0 (automatically generated log message) imported from: moin--main--1.5--base-0
author Thomas Waldmann <tw-public@gmx.de>
date Thu, 22 Sep 2005 15:09:50 +0000
parents
children e80ad5feaba8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/wikixml/marshal.py	Thu Sep 22 15:09:50 2005 +0000
@@ -0,0 +1,113 @@
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - XML Serialization
+
+    @copyright: 2002 by Jürgen Hermann <jh@web.de>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+import types
+
+
+class Marshal:
+    """ Serialize Python data structures to XML.
+
+        XML_DECL is the standard XML declaration.
+
+        The class attributes ROOT_CONTAINER (default "data") and
+        ITEM_CONTAINER (default "item") can be overwritten by derived
+        classes; if ROOT_CONTAINER is `None`, the usually generated
+        container element is omitted, the same is true for ITEM_CONTAINER.
+        
+        PRIVATE_PREFIXES is a list of prefixes of tagnames that are
+        treated as private, i.e. things that should not be serialized.
+        Default is to omit all properties starting with an underscore.
+
+        TAG_MAP is a translation table for tag names, and is empty by
+        default. It can also be used to surpress certain properties by
+        mapping a tag name to `None`.
+    """
+
+    # Convenience: Standard-XML-Deklaration
+    XML_DECL = '<?xml version="1.0" encoding="ISO-8859-1"?>\n'
+
+    # Container Tags
+    ROOT_CONTAINER = "data"
+    ITEM_CONTAINER = "item"
+    
+    # List of private prefixes
+    PRIVATE_PREFIXES = ['_']
+
+    # Translation map
+    TAG_MAP = {}
+
+
+    def __toXML(self, element, data): 
+        """ Recursive helper method that transforms an object to XML.
+        
+            Returns a list of strings, which constitute the XML document.
+        """
+        # map tag names
+        if self.TAG_MAP:
+            element = self.TAG_MAP.get(element, element)
+
+        if element:
+            for prefix in self.PRIVATE_PREFIXES:
+                if element.startswith(prefix): return ''
+            content = ['<%s>' % element]
+        else:
+            content = []
+
+        # Handle the different data types
+        add_content = content.extend
+
+        if data is None:
+            content = "<none/>"
+
+        elif isinstance(data, types.StringType):
+            # String
+            content = (data.replace("&", "&amp;") # Must be done first!
+                           .replace("<", "&lt;")
+                           .replace(">", "&gt;"))
+
+        elif isinstance(data, types.DictionaryType):
+            # Dictionary
+            for key, value in data.items():
+                add_content(self.__toXML(key, value))
+
+        elif isinstance(data, types.ListType) or isinstance(data, types.TupleType):
+            # List or Tuple
+            for item in data:
+                add_content(self.__toXML(self.ITEM_CONTAINER, item))
+
+        elif hasattr(data, "toXML"):
+            add_content([data.toXML()])
+
+        elif hasattr(data, "__dict__"):
+            add_content(self.__toXML(self.ROOT_CONTAINER, data.__dict__))
+
+        else:
+            # Everything else
+            content = (str(data).replace("&", "&amp;") # Must be done first!
+                                .replace("<", "&lt;")
+                                .replace(">", "&gt;"))
+
+        # Close container element
+        if isinstance(content, types.StringType):
+            # No Whitespace
+            if element:
+                content = ['<%s>%s</%s>' % (element, content, element)]
+            else:
+                content = [content]
+        elif element:
+            # Whitespace
+            content.append('</%s>' % element)
+
+        return content
+
+
+    def toXML(self):
+        """ Transform an instance to an XML string.
+        """
+        return '\n'.join(self.__toXML(self.ROOT_CONTAINER, self.__dict__))
+