aboutsummaryrefslogtreecommitdiff
path: root/mammoth
diff options
context:
space:
mode:
Diffstat (limited to 'mammoth')
-rw-r--r--mammoth/docx/xmlparser.py101
1 files changed, 44 insertions, 57 deletions
diff --git a/mammoth/docx/xmlparser.py b/mammoth/docx/xmlparser.py
index 4e963db..bb84afd 100644
--- a/mammoth/docx/xmlparser.py
+++ b/mammoth/docx/xmlparser.py
@@ -1,4 +1,4 @@
-import xml.sax
+import xml.dom.minidom
import cobble
@@ -8,16 +8,16 @@ class XmlElement(object):
name = cobble.field()
attributes = cobble.field()
children = cobble.field()
-
+
def find_child_or_null(self, name):
return self.find_child(name) or _null_xml_element
-
+
def find_child(self, name):
for child in self.children:
if isinstance(child, XmlElement) and child.name == name:
return child
-
-
+
+
def find_children(self, name):
return XmlElementList(filter(
lambda child: child.node_type == node_types.element and child.name == name,
@@ -28,10 +28,10 @@ class XmlElement(object):
class XmlElementList(object):
def __init__(self, elements):
self._elements = elements
-
+
def __iter__(self):
return iter(self._elements)
-
+
def find_children(self, name):
children = []
for element in self._elements:
@@ -42,10 +42,10 @@ class XmlElementList(object):
class NullXmlElement(object):
attributes = {}
-
+
def find_child_or_null(self, name):
return self
-
+
def find_child(self, name):
return None
@@ -79,55 +79,42 @@ def parse_xml(fileobj, namespace_mapping=None):
namespace_prefixes = {}
else:
namespace_prefixes = dict((uri, prefix) for prefix, uri in namespace_mapping)
-
- handler = Handler(namespace_prefixes)
- parser = xml.sax.make_parser()
- parser.setFeature(xml.sax.handler.feature_namespaces, True)
- parser.setContentHandler(handler)
- parser.parse(fileobj)
- return handler.root()
-
-
-class Handler(xml.sax.handler.ContentHandler):
- def __init__(self, namespace_prefixes):
- self._namespace_prefixes = namespace_prefixes
- self._element_stack = [RootElement()]
- self._character_buffer = []
-
- def root(self):
- return self._element_stack[0].children[0]
-
- def startElementNS(self, name, qname, attrs):
- self._flush_character_buffer()
- attributes = dict((self._read_name(key), value) for key, value in attrs.items())
- element = XmlElement(self._read_name(name), attributes, [])
- self._element_stack[-1].children.append(element)
- self._element_stack.append(element)
-
- def endElementNS(self, name, qname):
- self._flush_character_buffer()
- self._element_stack.pop()
-
- def characters(self, content):
- self._character_buffer.append(content)
-
- def _flush_character_buffer(self):
- if self._character_buffer:
- text = "".join(self._character_buffer)
- self._element_stack[-1].children.append(XmlText(text))
- self._character_buffer = []
-
- def _read_name(self, name):
- uri, local_name = name
- if uri is None:
- return local_name
+
+ document = xml.dom.minidom.parse(fileobj)
+
+ def convert_node(node):
+ if node.nodeType == xml.dom.Node.ELEMENT_NODE:
+ return convert_element(node)
+ elif node.nodeType == xml.dom.Node.TEXT_NODE:
+ return XmlText(node.nodeValue)
+ else:
+ return None
+
+ def convert_element(element):
+ converted_name = convert_name(element)
+
+ converted_attributes = dict(
+ (convert_name(attribute), attribute.value)
+ for attribute in element.attributes.values()
+ if attribute.namespaceURI != "http://www.w3.org/2000/xmlns/"
+ )
+
+ converted_children = []
+ for child_node in element.childNodes:
+ converted_child_node = convert_node(child_node)
+ if converted_child_node is not None:
+ converted_children.append(converted_child_node)
+
+ return XmlElement(converted_name, converted_attributes, converted_children)
+
+ def convert_name(node):
+ if node.namespaceURI is None:
+ return node.localName
else:
- prefix = self._namespace_prefixes.get(uri)
+ prefix = namespace_prefixes.get(node.namespaceURI)
if prefix is None:
- return "{%s}%s" % (uri, local_name)
+ return "{%s}%s" % (node.namespaceURI, node.localName)
else:
- return "%s:%s" % (prefix, local_name)
+ return "%s:%s" % (prefix, node.localName)
-class RootElement(object):
- def __init__(self):
- self.children = []
+ return convert_node(document.documentElement)