]> git.proxmox.com Git - mirror_edk2.git/blobdiff - AppPkg/Applications/Python/Python-2.7.10/Lib/xml/dom/expatbuilder.py
edk2: Remove AppPkg, StdLib, StdLibPrivateInternalFiles
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / Lib / xml / dom / expatbuilder.py
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Lib/xml/dom/expatbuilder.py b/AppPkg/Applications/Python/Python-2.7.10/Lib/xml/dom/expatbuilder.py
deleted file mode 100644 (file)
index 95c23a0..0000000
+++ /dev/null
@@ -1,983 +0,0 @@
-"""Facility to use the Expat parser to load a minidom instance\r
-from a string or file.\r
-\r
-This avoids all the overhead of SAX and pulldom to gain performance.\r
-"""\r
-\r
-# Warning!\r
-#\r
-# This module is tightly bound to the implementation details of the\r
-# minidom DOM and can't be used with other DOM implementations.  This\r
-# is due, in part, to a lack of appropriate methods in the DOM (there is\r
-# no way to create Entity and Notation nodes via the DOM Level 2\r
-# interface), and for performance.  The later is the cause of some fairly\r
-# cryptic code.\r
-#\r
-# Performance hacks:\r
-#\r
-#   -  .character_data_handler() has an extra case in which continuing\r
-#      data is appended to an existing Text node; this can be a\r
-#      speedup since pyexpat can break up character data into multiple\r
-#      callbacks even though we set the buffer_text attribute on the\r
-#      parser.  This also gives us the advantage that we don't need a\r
-#      separate normalization pass.\r
-#\r
-#   -  Determining that a node exists is done using an identity comparison\r
-#      with None rather than a truth test; this avoids searching for and\r
-#      calling any methods on the node object if it exists.  (A rather\r
-#      nice speedup is achieved this way as well!)\r
-\r
-from xml.dom import xmlbuilder, minidom, Node\r
-from xml.dom import EMPTY_NAMESPACE, EMPTY_PREFIX, XMLNS_NAMESPACE\r
-from xml.parsers import expat\r
-from xml.dom.minidom import _append_child, _set_attribute_node\r
-from xml.dom.NodeFilter import NodeFilter\r
-\r
-from xml.dom.minicompat import *\r
-\r
-TEXT_NODE = Node.TEXT_NODE\r
-CDATA_SECTION_NODE = Node.CDATA_SECTION_NODE\r
-DOCUMENT_NODE = Node.DOCUMENT_NODE\r
-\r
-FILTER_ACCEPT = xmlbuilder.DOMBuilderFilter.FILTER_ACCEPT\r
-FILTER_REJECT = xmlbuilder.DOMBuilderFilter.FILTER_REJECT\r
-FILTER_SKIP = xmlbuilder.DOMBuilderFilter.FILTER_SKIP\r
-FILTER_INTERRUPT = xmlbuilder.DOMBuilderFilter.FILTER_INTERRUPT\r
-\r
-theDOMImplementation = minidom.getDOMImplementation()\r
-\r
-# Expat typename -> TypeInfo\r
-_typeinfo_map = {\r
-    "CDATA":    minidom.TypeInfo(None, "cdata"),\r
-    "ENUM":     minidom.TypeInfo(None, "enumeration"),\r
-    "ENTITY":   minidom.TypeInfo(None, "entity"),\r
-    "ENTITIES": minidom.TypeInfo(None, "entities"),\r
-    "ID":       minidom.TypeInfo(None, "id"),\r
-    "IDREF":    minidom.TypeInfo(None, "idref"),\r
-    "IDREFS":   minidom.TypeInfo(None, "idrefs"),\r
-    "NMTOKEN":  minidom.TypeInfo(None, "nmtoken"),\r
-    "NMTOKENS": minidom.TypeInfo(None, "nmtokens"),\r
-    }\r
-\r
-class ElementInfo(object):\r
-    __slots__ = '_attr_info', '_model', 'tagName'\r
-\r
-    def __init__(self, tagName, model=None):\r
-        self.tagName = tagName\r
-        self._attr_info = []\r
-        self._model = model\r
-\r
-    def __getstate__(self):\r
-        return self._attr_info, self._model, self.tagName\r
-\r
-    def __setstate__(self, state):\r
-        self._attr_info, self._model, self.tagName = state\r
-\r
-    def getAttributeType(self, aname):\r
-        for info in self._attr_info:\r
-            if info[1] == aname:\r
-                t = info[-2]\r
-                if t[0] == "(":\r
-                    return _typeinfo_map["ENUM"]\r
-                else:\r
-                    return _typeinfo_map[info[-2]]\r
-        return minidom._no_type\r
-\r
-    def getAttributeTypeNS(self, namespaceURI, localName):\r
-        return minidom._no_type\r
-\r
-    def isElementContent(self):\r
-        if self._model:\r
-            type = self._model[0]\r
-            return type not in (expat.model.XML_CTYPE_ANY,\r
-                                expat.model.XML_CTYPE_MIXED)\r
-        else:\r
-            return False\r
-\r
-    def isEmpty(self):\r
-        if self._model:\r
-            return self._model[0] == expat.model.XML_CTYPE_EMPTY\r
-        else:\r
-            return False\r
-\r
-    def isId(self, aname):\r
-        for info in self._attr_info:\r
-            if info[1] == aname:\r
-                return info[-2] == "ID"\r
-        return False\r
-\r
-    def isIdNS(self, euri, ename, auri, aname):\r
-        # not sure this is meaningful\r
-        return self.isId((auri, aname))\r
-\r
-def _intern(builder, s):\r
-    return builder._intern_setdefault(s, s)\r
-\r
-def _parse_ns_name(builder, name):\r
-    assert ' ' in name\r
-    parts = name.split(' ')\r
-    intern = builder._intern_setdefault\r
-    if len(parts) == 3:\r
-        uri, localname, prefix = parts\r
-        prefix = intern(prefix, prefix)\r
-        qname = "%s:%s" % (prefix, localname)\r
-        qname = intern(qname, qname)\r
-        localname = intern(localname, localname)\r
-    else:\r
-        uri, localname = parts\r
-        prefix = EMPTY_PREFIX\r
-        qname = localname = intern(localname, localname)\r
-    return intern(uri, uri), localname, prefix, qname\r
-\r
-\r
-class ExpatBuilder:\r
-    """Document builder that uses Expat to build a ParsedXML.DOM document\r
-    instance."""\r
-\r
-    def __init__(self, options=None):\r
-        if options is None:\r
-            options = xmlbuilder.Options()\r
-        self._options = options\r
-        if self._options.filter is not None:\r
-            self._filter = FilterVisibilityController(self._options.filter)\r
-        else:\r
-            self._filter = None\r
-            # This *really* doesn't do anything in this case, so\r
-            # override it with something fast & minimal.\r
-            self._finish_start_element = id\r
-        self._parser = None\r
-        self.reset()\r
-\r
-    def createParser(self):\r
-        """Create a new parser object."""\r
-        return expat.ParserCreate()\r
-\r
-    def getParser(self):\r
-        """Return the parser object, creating a new one if needed."""\r
-        if not self._parser:\r
-            self._parser = self.createParser()\r
-            self._intern_setdefault = self._parser.intern.setdefault\r
-            self._parser.buffer_text = True\r
-            self._parser.ordered_attributes = True\r
-            self._parser.specified_attributes = True\r
-            self.install(self._parser)\r
-        return self._parser\r
-\r
-    def reset(self):\r
-        """Free all data structures used during DOM construction."""\r
-        self.document = theDOMImplementation.createDocument(\r
-            EMPTY_NAMESPACE, None, None)\r
-        self.curNode = self.document\r
-        self._elem_info = self.document._elem_info\r
-        self._cdata = False\r
-\r
-    def install(self, parser):\r
-        """Install the callbacks needed to build the DOM into the parser."""\r
-        # This creates circular references!\r
-        parser.StartDoctypeDeclHandler = self.start_doctype_decl_handler\r
-        parser.StartElementHandler = self.first_element_handler\r
-        parser.EndElementHandler = self.end_element_handler\r
-        parser.ProcessingInstructionHandler = self.pi_handler\r
-        if self._options.entities:\r
-            parser.EntityDeclHandler = self.entity_decl_handler\r
-        parser.NotationDeclHandler = self.notation_decl_handler\r
-        if self._options.comments:\r
-            parser.CommentHandler = self.comment_handler\r
-        if self._options.cdata_sections:\r
-            parser.StartCdataSectionHandler = self.start_cdata_section_handler\r
-            parser.EndCdataSectionHandler = self.end_cdata_section_handler\r
-            parser.CharacterDataHandler = self.character_data_handler_cdata\r
-        else:\r
-            parser.CharacterDataHandler = self.character_data_handler\r
-        parser.ExternalEntityRefHandler = self.external_entity_ref_handler\r
-        parser.XmlDeclHandler = self.xml_decl_handler\r
-        parser.ElementDeclHandler = self.element_decl_handler\r
-        parser.AttlistDeclHandler = self.attlist_decl_handler\r
-\r
-    def parseFile(self, file):\r
-        """Parse a document from a file object, returning the document\r
-        node."""\r
-        parser = self.getParser()\r
-        first_buffer = True\r
-        try:\r
-            while 1:\r
-                buffer = file.read(16*1024)\r
-                if not buffer:\r
-                    break\r
-                parser.Parse(buffer, 0)\r
-                if first_buffer and self.document.documentElement:\r
-                    self._setup_subset(buffer)\r
-                first_buffer = False\r
-            parser.Parse("", True)\r
-        except ParseEscape:\r
-            pass\r
-        doc = self.document\r
-        self.reset()\r
-        self._parser = None\r
-        return doc\r
-\r
-    def parseString(self, string):\r
-        """Parse a document from a string, returning the document node."""\r
-        parser = self.getParser()\r
-        try:\r
-            parser.Parse(string, True)\r
-            self._setup_subset(string)\r
-        except ParseEscape:\r
-            pass\r
-        doc = self.document\r
-        self.reset()\r
-        self._parser = None\r
-        return doc\r
-\r
-    def _setup_subset(self, buffer):\r
-        """Load the internal subset if there might be one."""\r
-        if self.document.doctype:\r
-            extractor = InternalSubsetExtractor()\r
-            extractor.parseString(buffer)\r
-            subset = extractor.getSubset()\r
-            self.document.doctype.internalSubset = subset\r
-\r
-    def start_doctype_decl_handler(self, doctypeName, systemId, publicId,\r
-                                   has_internal_subset):\r
-        doctype = self.document.implementation.createDocumentType(\r
-            doctypeName, publicId, systemId)\r
-        doctype.ownerDocument = self.document\r
-        _append_child(self.document, doctype)\r
-        self.document.doctype = doctype\r
-        if self._filter and self._filter.acceptNode(doctype) == FILTER_REJECT:\r
-            self.document.doctype = None\r
-            del self.document.childNodes[-1]\r
-            doctype = None\r
-            self._parser.EntityDeclHandler = None\r
-            self._parser.NotationDeclHandler = None\r
-        if has_internal_subset:\r
-            if doctype is not None:\r
-                doctype.entities._seq = []\r
-                doctype.notations._seq = []\r
-            self._parser.CommentHandler = None\r
-            self._parser.ProcessingInstructionHandler = None\r
-            self._parser.EndDoctypeDeclHandler = self.end_doctype_decl_handler\r
-\r
-    def end_doctype_decl_handler(self):\r
-        if self._options.comments:\r
-            self._parser.CommentHandler = self.comment_handler\r
-        self._parser.ProcessingInstructionHandler = self.pi_handler\r
-        if not (self._elem_info or self._filter):\r
-            self._finish_end_element = id\r
-\r
-    def pi_handler(self, target, data):\r
-        node = self.document.createProcessingInstruction(target, data)\r
-        _append_child(self.curNode, node)\r
-        if self._filter and self._filter.acceptNode(node) == FILTER_REJECT:\r
-            self.curNode.removeChild(node)\r
-\r
-    def character_data_handler_cdata(self, data):\r
-        childNodes = self.curNode.childNodes\r
-        if self._cdata:\r
-            if (  self._cdata_continue\r
-                  and childNodes[-1].nodeType == CDATA_SECTION_NODE):\r
-                childNodes[-1].appendData(data)\r
-                return\r
-            node = self.document.createCDATASection(data)\r
-            self._cdata_continue = True\r
-        elif childNodes and childNodes[-1].nodeType == TEXT_NODE:\r
-            node = childNodes[-1]\r
-            value = node.data + data\r
-            d = node.__dict__\r
-            d['data'] = d['nodeValue'] = value\r
-            return\r
-        else:\r
-            node = minidom.Text()\r
-            d = node.__dict__\r
-            d['data'] = d['nodeValue'] = data\r
-            d['ownerDocument'] = self.document\r
-        _append_child(self.curNode, node)\r
-\r
-    def character_data_handler(self, data):\r
-        childNodes = self.curNode.childNodes\r
-        if childNodes and childNodes[-1].nodeType == TEXT_NODE:\r
-            node = childNodes[-1]\r
-            d = node.__dict__\r
-            d['data'] = d['nodeValue'] = node.data + data\r
-            return\r
-        node = minidom.Text()\r
-        d = node.__dict__\r
-        d['data'] = d['nodeValue'] = node.data + data\r
-        d['ownerDocument'] = self.document\r
-        _append_child(self.curNode, node)\r
-\r
-    def entity_decl_handler(self, entityName, is_parameter_entity, value,\r
-                            base, systemId, publicId, notationName):\r
-        if is_parameter_entity:\r
-            # we don't care about parameter entities for the DOM\r
-            return\r
-        if not self._options.entities:\r
-            return\r
-        node = self.document._create_entity(entityName, publicId,\r
-                                            systemId, notationName)\r
-        if value is not None:\r
-            # internal entity\r
-            # node *should* be readonly, but we'll cheat\r
-            child = self.document.createTextNode(value)\r
-            node.childNodes.append(child)\r
-        self.document.doctype.entities._seq.append(node)\r
-        if self._filter and self._filter.acceptNode(node) == FILTER_REJECT:\r
-            del self.document.doctype.entities._seq[-1]\r
-\r
-    def notation_decl_handler(self, notationName, base, systemId, publicId):\r
-        node = self.document._create_notation(notationName, publicId, systemId)\r
-        self.document.doctype.notations._seq.append(node)\r
-        if self._filter and self._filter.acceptNode(node) == FILTER_ACCEPT:\r
-            del self.document.doctype.notations._seq[-1]\r
-\r
-    def comment_handler(self, data):\r
-        node = self.document.createComment(data)\r
-        _append_child(self.curNode, node)\r
-        if self._filter and self._filter.acceptNode(node) == FILTER_REJECT:\r
-            self.curNode.removeChild(node)\r
-\r
-    def start_cdata_section_handler(self):\r
-        self._cdata = True\r
-        self._cdata_continue = False\r
-\r
-    def end_cdata_section_handler(self):\r
-        self._cdata = False\r
-        self._cdata_continue = False\r
-\r
-    def external_entity_ref_handler(self, context, base, systemId, publicId):\r
-        return 1\r
-\r
-    def first_element_handler(self, name, attributes):\r
-        if self._filter is None and not self._elem_info:\r
-            self._finish_end_element = id\r
-        self.getParser().StartElementHandler = self.start_element_handler\r
-        self.start_element_handler(name, attributes)\r
-\r
-    def start_element_handler(self, name, attributes):\r
-        node = self.document.createElement(name)\r
-        _append_child(self.curNode, node)\r
-        self.curNode = node\r
-\r
-        if attributes:\r
-            for i in range(0, len(attributes), 2):\r
-                a = minidom.Attr(attributes[i], EMPTY_NAMESPACE,\r
-                                 None, EMPTY_PREFIX)\r
-                value = attributes[i+1]\r
-                d = a.childNodes[0].__dict__\r
-                d['data'] = d['nodeValue'] = value\r
-                d = a.__dict__\r
-                d['value'] = d['nodeValue'] = value\r
-                d['ownerDocument'] = self.document\r
-                _set_attribute_node(node, a)\r
-\r
-        if node is not self.document.documentElement:\r
-            self._finish_start_element(node)\r
-\r
-    def _finish_start_element(self, node):\r
-        if self._filter:\r
-            # To be general, we'd have to call isSameNode(), but this\r
-            # is sufficient for minidom:\r
-            if node is self.document.documentElement:\r
-                return\r
-            filt = self._filter.startContainer(node)\r
-            if filt == FILTER_REJECT:\r
-                # ignore this node & all descendents\r
-                Rejecter(self)\r
-            elif filt == FILTER_SKIP:\r
-                # ignore this node, but make it's children become\r
-                # children of the parent node\r
-                Skipper(self)\r
-            else:\r
-                return\r
-            self.curNode = node.parentNode\r
-            node.parentNode.removeChild(node)\r
-            node.unlink()\r
-\r
-    # If this ever changes, Namespaces.end_element_handler() needs to\r
-    # be changed to match.\r
-    #\r
-    def end_element_handler(self, name):\r
-        curNode = self.curNode\r
-        self.curNode = curNode.parentNode\r
-        self._finish_end_element(curNode)\r
-\r
-    def _finish_end_element(self, curNode):\r
-        info = self._elem_info.get(curNode.tagName)\r
-        if info:\r
-            self._handle_white_text_nodes(curNode, info)\r
-        if self._filter:\r
-            if curNode is self.document.documentElement:\r
-                return\r
-            if self._filter.acceptNode(curNode) == FILTER_REJECT:\r
-                self.curNode.removeChild(curNode)\r
-                curNode.unlink()\r
-\r
-    def _handle_white_text_nodes(self, node, info):\r
-        if (self._options.whitespace_in_element_content\r
-            or not info.isElementContent()):\r
-            return\r
-\r
-        # We have element type information and should remove ignorable\r
-        # whitespace; identify for text nodes which contain only\r
-        # whitespace.\r
-        L = []\r
-        for child in node.childNodes:\r
-            if child.nodeType == TEXT_NODE and not child.data.strip():\r
-                L.append(child)\r
-\r
-        # Remove ignorable whitespace from the tree.\r
-        for child in L:\r
-            node.removeChild(child)\r
-\r
-    def element_decl_handler(self, name, model):\r
-        info = self._elem_info.get(name)\r
-        if info is None:\r
-            self._elem_info[name] = ElementInfo(name, model)\r
-        else:\r
-            assert info._model is None\r
-            info._model = model\r
-\r
-    def attlist_decl_handler(self, elem, name, type, default, required):\r
-        info = self._elem_info.get(elem)\r
-        if info is None:\r
-            info = ElementInfo(elem)\r
-            self._elem_info[elem] = info\r
-        info._attr_info.append(\r
-            [None, name, None, None, default, 0, type, required])\r
-\r
-    def xml_decl_handler(self, version, encoding, standalone):\r
-        self.document.version = version\r
-        self.document.encoding = encoding\r
-        # This is still a little ugly, thanks to the pyexpat API. ;-(\r
-        if standalone >= 0:\r
-            if standalone:\r
-                self.document.standalone = True\r
-            else:\r
-                self.document.standalone = False\r
-\r
-\r
-# Don't include FILTER_INTERRUPT, since that's checked separately\r
-# where allowed.\r
-_ALLOWED_FILTER_RETURNS = (FILTER_ACCEPT, FILTER_REJECT, FILTER_SKIP)\r
-\r
-class FilterVisibilityController(object):\r
-    """Wrapper around a DOMBuilderFilter which implements the checks\r
-    to make the whatToShow filter attribute work."""\r
-\r
-    __slots__ = 'filter',\r
-\r
-    def __init__(self, filter):\r
-        self.filter = filter\r
-\r
-    def startContainer(self, node):\r
-        mask = self._nodetype_mask[node.nodeType]\r
-        if self.filter.whatToShow & mask:\r
-            val = self.filter.startContainer(node)\r
-            if val == FILTER_INTERRUPT:\r
-                raise ParseEscape\r
-            if val not in _ALLOWED_FILTER_RETURNS:\r
-                raise ValueError, \\r
-                      "startContainer() returned illegal value: " + repr(val)\r
-            return val\r
-        else:\r
-            return FILTER_ACCEPT\r
-\r
-    def acceptNode(self, node):\r
-        mask = self._nodetype_mask[node.nodeType]\r
-        if self.filter.whatToShow & mask:\r
-            val = self.filter.acceptNode(node)\r
-            if val == FILTER_INTERRUPT:\r
-                raise ParseEscape\r
-            if val == FILTER_SKIP:\r
-                # move all child nodes to the parent, and remove this node\r
-                parent = node.parentNode\r
-                for child in node.childNodes[:]:\r
-                    parent.appendChild(child)\r
-                # node is handled by the caller\r
-                return FILTER_REJECT\r
-            if val not in _ALLOWED_FILTER_RETURNS:\r
-                raise ValueError, \\r
-                      "acceptNode() returned illegal value: " + repr(val)\r
-            return val\r
-        else:\r
-            return FILTER_ACCEPT\r
-\r
-    _nodetype_mask = {\r
-        Node.ELEMENT_NODE:                NodeFilter.SHOW_ELEMENT,\r
-        Node.ATTRIBUTE_NODE:              NodeFilter.SHOW_ATTRIBUTE,\r
-        Node.TEXT_NODE:                   NodeFilter.SHOW_TEXT,\r
-        Node.CDATA_SECTION_NODE:          NodeFilter.SHOW_CDATA_SECTION,\r
-        Node.ENTITY_REFERENCE_NODE:       NodeFilter.SHOW_ENTITY_REFERENCE,\r
-        Node.ENTITY_NODE:                 NodeFilter.SHOW_ENTITY,\r
-        Node.PROCESSING_INSTRUCTION_NODE: NodeFilter.SHOW_PROCESSING_INSTRUCTION,\r
-        Node.COMMENT_NODE:                NodeFilter.SHOW_COMMENT,\r
-        Node.DOCUMENT_NODE:               NodeFilter.SHOW_DOCUMENT,\r
-        Node.DOCUMENT_TYPE_NODE:          NodeFilter.SHOW_DOCUMENT_TYPE,\r
-        Node.DOCUMENT_FRAGMENT_NODE:      NodeFilter.SHOW_DOCUMENT_FRAGMENT,\r
-        Node.NOTATION_NODE:               NodeFilter.SHOW_NOTATION,\r
-        }\r
-\r
-\r
-class FilterCrutch(object):\r
-    __slots__ = '_builder', '_level', '_old_start', '_old_end'\r
-\r
-    def __init__(self, builder):\r
-        self._level = 0\r
-        self._builder = builder\r
-        parser = builder._parser\r
-        self._old_start = parser.StartElementHandler\r
-        self._old_end = parser.EndElementHandler\r
-        parser.StartElementHandler = self.start_element_handler\r
-        parser.EndElementHandler = self.end_element_handler\r
-\r
-class Rejecter(FilterCrutch):\r
-    __slots__ = ()\r
-\r
-    def __init__(self, builder):\r
-        FilterCrutch.__init__(self, builder)\r
-        parser = builder._parser\r
-        for name in ("ProcessingInstructionHandler",\r
-                     "CommentHandler",\r
-                     "CharacterDataHandler",\r
-                     "StartCdataSectionHandler",\r
-                     "EndCdataSectionHandler",\r
-                     "ExternalEntityRefHandler",\r
-                     ):\r
-            setattr(parser, name, None)\r
-\r
-    def start_element_handler(self, *args):\r
-        self._level = self._level + 1\r
-\r
-    def end_element_handler(self, *args):\r
-        if self._level == 0:\r
-            # restore the old handlers\r
-            parser = self._builder._parser\r
-            self._builder.install(parser)\r
-            parser.StartElementHandler = self._old_start\r
-            parser.EndElementHandler = self._old_end\r
-        else:\r
-            self._level = self._level - 1\r
-\r
-class Skipper(FilterCrutch):\r
-    __slots__ = ()\r
-\r
-    def start_element_handler(self, *args):\r
-        node = self._builder.curNode\r
-        self._old_start(*args)\r
-        if self._builder.curNode is not node:\r
-            self._level = self._level + 1\r
-\r
-    def end_element_handler(self, *args):\r
-        if self._level == 0:\r
-            # We're popping back out of the node we're skipping, so we\r
-            # shouldn't need to do anything but reset the handlers.\r
-            self._builder._parser.StartElementHandler = self._old_start\r
-            self._builder._parser.EndElementHandler = self._old_end\r
-            self._builder = None\r
-        else:\r
-            self._level = self._level - 1\r
-            self._old_end(*args)\r
-\r
-\r
-# framework document used by the fragment builder.\r
-# Takes a string for the doctype, subset string, and namespace attrs string.\r
-\r
-_FRAGMENT_BUILDER_INTERNAL_SYSTEM_ID = \\r
-    "http://xml.python.org/entities/fragment-builder/internal"\r
-\r
-_FRAGMENT_BUILDER_TEMPLATE = (\r
-    '''\\r
-<!DOCTYPE wrapper\r
-  %%s [\r
-  <!ENTITY fragment-builder-internal\r
-    SYSTEM "%s">\r
-%%s\r
-]>\r
-<wrapper %%s\r
->&fragment-builder-internal;</wrapper>'''\r
-    % _FRAGMENT_BUILDER_INTERNAL_SYSTEM_ID)\r
-\r
-\r
-class FragmentBuilder(ExpatBuilder):\r
-    """Builder which constructs document fragments given XML source\r
-    text and a context node.\r
-\r
-    The context node is expected to provide information about the\r
-    namespace declarations which are in scope at the start of the\r
-    fragment.\r
-    """\r
-\r
-    def __init__(self, context, options=None):\r
-        if context.nodeType == DOCUMENT_NODE:\r
-            self.originalDocument = context\r
-            self.context = context\r
-        else:\r
-            self.originalDocument = context.ownerDocument\r
-            self.context = context\r
-        ExpatBuilder.__init__(self, options)\r
-\r
-    def reset(self):\r
-        ExpatBuilder.reset(self)\r
-        self.fragment = None\r
-\r
-    def parseFile(self, file):\r
-        """Parse a document fragment from a file object, returning the\r
-        fragment node."""\r
-        return self.parseString(file.read())\r
-\r
-    def parseString(self, string):\r
-        """Parse a document fragment from a string, returning the\r
-        fragment node."""\r
-        self._source = string\r
-        parser = self.getParser()\r
-        doctype = self.originalDocument.doctype\r
-        ident = ""\r
-        if doctype:\r
-            subset = doctype.internalSubset or self._getDeclarations()\r
-            if doctype.publicId:\r
-                ident = ('PUBLIC "%s" "%s"'\r
-                         % (doctype.publicId, doctype.systemId))\r
-            elif doctype.systemId:\r
-                ident = 'SYSTEM "%s"' % doctype.systemId\r
-        else:\r
-            subset = ""\r
-        nsattrs = self._getNSattrs() # get ns decls from node's ancestors\r
-        document = _FRAGMENT_BUILDER_TEMPLATE % (ident, subset, nsattrs)\r
-        try:\r
-            parser.Parse(document, 1)\r
-        except:\r
-            self.reset()\r
-            raise\r
-        fragment = self.fragment\r
-        self.reset()\r
-##         self._parser = None\r
-        return fragment\r
-\r
-    def _getDeclarations(self):\r
-        """Re-create the internal subset from the DocumentType node.\r
-\r
-        This is only needed if we don't already have the\r
-        internalSubset as a string.\r
-        """\r
-        doctype = self.context.ownerDocument.doctype\r
-        s = ""\r
-        if doctype:\r
-            for i in range(doctype.notations.length):\r
-                notation = doctype.notations.item(i)\r
-                if s:\r
-                    s = s + "\n  "\r
-                s = "%s<!NOTATION %s" % (s, notation.nodeName)\r
-                if notation.publicId:\r
-                    s = '%s PUBLIC "%s"\n             "%s">' \\r
-                        % (s, notation.publicId, notation.systemId)\r
-                else:\r
-                    s = '%s SYSTEM "%s">' % (s, notation.systemId)\r
-            for i in range(doctype.entities.length):\r
-                entity = doctype.entities.item(i)\r
-                if s:\r
-                    s = s + "\n  "\r
-                s = "%s<!ENTITY %s" % (s, entity.nodeName)\r
-                if entity.publicId:\r
-                    s = '%s PUBLIC "%s"\n             "%s"' \\r
-                        % (s, entity.publicId, entity.systemId)\r
-                elif entity.systemId:\r
-                    s = '%s SYSTEM "%s"' % (s, entity.systemId)\r
-                else:\r
-                    s = '%s "%s"' % (s, entity.firstChild.data)\r
-                if entity.notationName:\r
-                    s = "%s NOTATION %s" % (s, entity.notationName)\r
-                s = s + ">"\r
-        return s\r
-\r
-    def _getNSattrs(self):\r
-        return ""\r
-\r
-    def external_entity_ref_handler(self, context, base, systemId, publicId):\r
-        if systemId == _FRAGMENT_BUILDER_INTERNAL_SYSTEM_ID:\r
-            # this entref is the one that we made to put the subtree\r
-            # in; all of our given input is parsed in here.\r
-            old_document = self.document\r
-            old_cur_node = self.curNode\r
-            parser = self._parser.ExternalEntityParserCreate(context)\r
-            # put the real document back, parse into the fragment to return\r
-            self.document = self.originalDocument\r
-            self.fragment = self.document.createDocumentFragment()\r
-            self.curNode = self.fragment\r
-            try:\r
-                parser.Parse(self._source, 1)\r
-            finally:\r
-                self.curNode = old_cur_node\r
-                self.document = old_document\r
-                self._source = None\r
-            return -1\r
-        else:\r
-            return ExpatBuilder.external_entity_ref_handler(\r
-                self, context, base, systemId, publicId)\r
-\r
-\r
-class Namespaces:\r
-    """Mix-in class for builders; adds support for namespaces."""\r
-\r
-    def _initNamespaces(self):\r
-        # list of (prefix, uri) ns declarations.  Namespace attrs are\r
-        # constructed from this and added to the element's attrs.\r
-        self._ns_ordered_prefixes = []\r
-\r
-    def createParser(self):\r
-        """Create a new namespace-handling parser."""\r
-        parser = expat.ParserCreate(namespace_separator=" ")\r
-        parser.namespace_prefixes = True\r
-        return parser\r
-\r
-    def install(self, parser):\r
-        """Insert the namespace-handlers onto the parser."""\r
-        ExpatBuilder.install(self, parser)\r
-        if self._options.namespace_declarations:\r
-            parser.StartNamespaceDeclHandler = (\r
-                self.start_namespace_decl_handler)\r
-\r
-    def start_namespace_decl_handler(self, prefix, uri):\r
-        """Push this namespace declaration on our storage."""\r
-        self._ns_ordered_prefixes.append((prefix, uri))\r
-\r
-    def start_element_handler(self, name, attributes):\r
-        if ' ' in name:\r
-            uri, localname, prefix, qname = _parse_ns_name(self, name)\r
-        else:\r
-            uri = EMPTY_NAMESPACE\r
-            qname = name\r
-            localname = None\r
-            prefix = EMPTY_PREFIX\r
-        node = minidom.Element(qname, uri, prefix, localname)\r
-        node.ownerDocument = self.document\r
-        _append_child(self.curNode, node)\r
-        self.curNode = node\r
-\r
-        if self._ns_ordered_prefixes:\r
-            for prefix, uri in self._ns_ordered_prefixes:\r
-                if prefix:\r
-                    a = minidom.Attr(_intern(self, 'xmlns:' + prefix),\r
-                                     XMLNS_NAMESPACE, prefix, "xmlns")\r
-                else:\r
-                    a = minidom.Attr("xmlns", XMLNS_NAMESPACE,\r
-                                     "xmlns", EMPTY_PREFIX)\r
-                d = a.childNodes[0].__dict__\r
-                d['data'] = d['nodeValue'] = uri\r
-                d = a.__dict__\r
-                d['value'] = d['nodeValue'] = uri\r
-                d['ownerDocument'] = self.document\r
-                _set_attribute_node(node, a)\r
-            del self._ns_ordered_prefixes[:]\r
-\r
-        if attributes:\r
-            _attrs = node._attrs\r
-            _attrsNS = node._attrsNS\r
-            for i in range(0, len(attributes), 2):\r
-                aname = attributes[i]\r
-                value = attributes[i+1]\r
-                if ' ' in aname:\r
-                    uri, localname, prefix, qname = _parse_ns_name(self, aname)\r
-                    a = minidom.Attr(qname, uri, localname, prefix)\r
-                    _attrs[qname] = a\r
-                    _attrsNS[(uri, localname)] = a\r
-                else:\r
-                    a = minidom.Attr(aname, EMPTY_NAMESPACE,\r
-                                     aname, EMPTY_PREFIX)\r
-                    _attrs[aname] = a\r
-                    _attrsNS[(EMPTY_NAMESPACE, aname)] = a\r
-                d = a.childNodes[0].__dict__\r
-                d['data'] = d['nodeValue'] = value\r
-                d = a.__dict__\r
-                d['ownerDocument'] = self.document\r
-                d['value'] = d['nodeValue'] = value\r
-                d['ownerElement'] = node\r
-\r
-    if __debug__:\r
-        # This only adds some asserts to the original\r
-        # end_element_handler(), so we only define this when -O is not\r
-        # used.  If changing one, be sure to check the other to see if\r
-        # it needs to be changed as well.\r
-        #\r
-        def end_element_handler(self, name):\r
-            curNode = self.curNode\r
-            if ' ' in name:\r
-                uri, localname, prefix, qname = _parse_ns_name(self, name)\r
-                assert (curNode.namespaceURI == uri\r
-                        and curNode.localName == localname\r
-                        and curNode.prefix == prefix), \\r
-                        "element stack messed up! (namespace)"\r
-            else:\r
-                assert curNode.nodeName == name, \\r
-                       "element stack messed up - bad nodeName"\r
-                assert curNode.namespaceURI == EMPTY_NAMESPACE, \\r
-                       "element stack messed up - bad namespaceURI"\r
-            self.curNode = curNode.parentNode\r
-            self._finish_end_element(curNode)\r
-\r
-\r
-class ExpatBuilderNS(Namespaces, ExpatBuilder):\r
-    """Document builder that supports namespaces."""\r
-\r
-    def reset(self):\r
-        ExpatBuilder.reset(self)\r
-        self._initNamespaces()\r
-\r
-\r
-class FragmentBuilderNS(Namespaces, FragmentBuilder):\r
-    """Fragment builder that supports namespaces."""\r
-\r
-    def reset(self):\r
-        FragmentBuilder.reset(self)\r
-        self._initNamespaces()\r
-\r
-    def _getNSattrs(self):\r
-        """Return string of namespace attributes from this element and\r
-        ancestors."""\r
-        # XXX This needs to be re-written to walk the ancestors of the\r
-        # context to build up the namespace information from\r
-        # declarations, elements, and attributes found in context.\r
-        # Otherwise we have to store a bunch more data on the DOM\r
-        # (though that *might* be more reliable -- not clear).\r
-        attrs = ""\r
-        context = self.context\r
-        L = []\r
-        while context:\r
-            if hasattr(context, '_ns_prefix_uri'):\r
-                for prefix, uri in context._ns_prefix_uri.items():\r
-                    # add every new NS decl from context to L and attrs string\r
-                    if prefix in L:\r
-                        continue\r
-                    L.append(prefix)\r
-                    if prefix:\r
-                        declname = "xmlns:" + prefix\r
-                    else:\r
-                        declname = "xmlns"\r
-                    if attrs:\r
-                        attrs = "%s\n    %s='%s'" % (attrs, declname, uri)\r
-                    else:\r
-                        attrs = " %s='%s'" % (declname, uri)\r
-            context = context.parentNode\r
-        return attrs\r
-\r
-\r
-class ParseEscape(Exception):\r
-    """Exception raised to short-circuit parsing in InternalSubsetExtractor."""\r
-    pass\r
-\r
-class InternalSubsetExtractor(ExpatBuilder):\r
-    """XML processor which can rip out the internal document type subset."""\r
-\r
-    subset = None\r
-\r
-    def getSubset(self):\r
-        """Return the internal subset as a string."""\r
-        return self.subset\r
-\r
-    def parseFile(self, file):\r
-        try:\r
-            ExpatBuilder.parseFile(self, file)\r
-        except ParseEscape:\r
-            pass\r
-\r
-    def parseString(self, string):\r
-        try:\r
-            ExpatBuilder.parseString(self, string)\r
-        except ParseEscape:\r
-            pass\r
-\r
-    def install(self, parser):\r
-        parser.StartDoctypeDeclHandler = self.start_doctype_decl_handler\r
-        parser.StartElementHandler = self.start_element_handler\r
-\r
-    def start_doctype_decl_handler(self, name, publicId, systemId,\r
-                                   has_internal_subset):\r
-        if has_internal_subset:\r
-            parser = self.getParser()\r
-            self.subset = []\r
-            parser.DefaultHandler = self.subset.append\r
-            parser.EndDoctypeDeclHandler = self.end_doctype_decl_handler\r
-        else:\r
-            raise ParseEscape()\r
-\r
-    def end_doctype_decl_handler(self):\r
-        s = ''.join(self.subset).replace('\r\n', '\n').replace('\r', '\n')\r
-        self.subset = s\r
-        raise ParseEscape()\r
-\r
-    def start_element_handler(self, name, attrs):\r
-        raise ParseEscape()\r
-\r
-\r
-def parse(file, namespaces=True):\r
-    """Parse a document, returning the resulting Document node.\r
-\r
-    'file' may be either a file name or an open file object.\r
-    """\r
-    if namespaces:\r
-        builder = ExpatBuilderNS()\r
-    else:\r
-        builder = ExpatBuilder()\r
-\r
-    if isinstance(file, StringTypes):\r
-        fp = open(file, 'rb')\r
-        try:\r
-            result = builder.parseFile(fp)\r
-        finally:\r
-            fp.close()\r
-    else:\r
-        result = builder.parseFile(file)\r
-    return result\r
-\r
-\r
-def parseString(string, namespaces=True):\r
-    """Parse a document from a string, returning the resulting\r
-    Document node.\r
-    """\r
-    if namespaces:\r
-        builder = ExpatBuilderNS()\r
-    else:\r
-        builder = ExpatBuilder()\r
-    return builder.parseString(string)\r
-\r
-\r
-def parseFragment(file, context, namespaces=True):\r
-    """Parse a fragment of a document, given the context from which it\r
-    was originally extracted.  context should be the parent of the\r
-    node(s) which are in the fragment.\r
-\r
-    'file' may be either a file name or an open file object.\r
-    """\r
-    if namespaces:\r
-        builder = FragmentBuilderNS(context)\r
-    else:\r
-        builder = FragmentBuilder(context)\r
-\r
-    if isinstance(file, StringTypes):\r
-        fp = open(file, 'rb')\r
-        try:\r
-            result = builder.parseFile(fp)\r
-        finally:\r
-            fp.close()\r
-    else:\r
-        result = builder.parseFile(file)\r
-    return result\r
-\r
-\r
-def parseFragmentString(string, context, namespaces=True):\r
-    """Parse a fragment of a document from a string, given the context\r
-    from which it was originally extracted.  context should be the\r
-    parent of the node(s) which are in the fragment.\r
-    """\r
-    if namespaces:\r
-        builder = FragmentBuilderNS(context)\r
-    else:\r
-        builder = FragmentBuilder(context)\r
-    return builder.parseString(string)\r
-\r
-\r
-def makeBuilder(options):\r
-    """Create a builder based on an Options object."""\r
-    if options.namespaces:\r
-        return ExpatBuilderNS(options)\r
-    else:\r
-        return ExpatBuilder(options)\r