Example #1
0
    def _inherit_context(self, node):
        '''_inherit_context(self, node) -> list
        Scan ancestors of attribute and namespace context.  Used only
        for single element node canonicalization, not for subset
        canonicalization.'''

        # Collect the initial list of xml:foo attributes.
        xmlattrs = filter(_IN_XML_NS, _attrs(node))

        # Walk up and get all xml:XXX attributes we inherit.
        inherited, parent = [], node.parentNode
        while parent and parent.nodeType == Node.ELEMENT_NODE:
            for a in filter(_IN_XML_NS, _attrs(parent)):
                n = a.localName
                if n not in xmlattrs:
                    xmlattrs.append(n)
                    inherited.append(a)
            parent = parent.parentNode
        return inherited
Example #2
0
 def GetElementNSdict(self, elt):
     '''Get a dictionary of all the namespace attributes for the indicated
     element.  The dictionaries are cached, and we recurse up the tree
     as necessary.
     '''
     d = self.ns_cache.get(id(elt))
     if not d:
         if elt != self.dom: d = self.GetElementNSdict(elt.parentNode)
         for a in _attrs(elt):
             if a.namespaceURI == XMLNS.BASE:
                 if a.localName == "xmlns":
                     d[''] = a.nodeValue
                 else:
                     d[a.localName] = a.nodeValue
         self.ns_cache[id(elt)] = d
     return d.copy()
Example #3
0
File: parse.py Project: 360ed/ZSI
 def GetElementNSdict(self, elt):
     '''Get a dictionary of all the namespace attributes for the indicated
     element.  The dictionaries are cached, and we recurse up the tree
     as necessary.
     '''
     d = self.ns_cache.get(id(elt))
     if not d:
         if elt != self.dom: d = self.GetElementNSdict(elt.parentNode)
         for a in _attrs(elt):
             if a.namespaceURI == XMLNS.BASE:
                 if a.localName == "xmlns":
                     d[''] = a.nodeValue
                 else:
                     d[a.localName] = a.nodeValue
         self.ns_cache[id(elt)] = d
     return d.copy()
Example #4
0
    def Receive(self, replytype=None, **kw):
        '''Parse message, create Python object. if replytype is None, use
        TC.Any to dynamically parse; otherwise it can be a Python class
        or the typecode to use in parsing.
        '''
        self.ReceiveSOAP(**kw)
        if self.ps.IsAFault():
            msg = FaultFromFaultMessage(self.ps)
            raise FaultException(msg)

        if replytype is None:
            tc = TC.Any(aslist=1)

            # if the message is RPC style, skip the fooBarResponse
            elt_name = '%s' % self.ps.body_root.localName
            if elt_name.find('Response') > 0:
                data = _child_elements(self.ps.body_root)
            else:
                data = [self.ps.body_root]
                
            if len(data) == 0: return None

            # check for array type, loop and process if found
            for attr in _attrs(data[0]):
                if attr.localName.find('arrayType') >= 0:
                    data = _child_elements(data[0])

                    toReturn = []
                    for node in data:
                        type = node.localName

                        # handle case where multiple elements are returned
                        if type.find('element') >= 0:
                            node = _child_elements(node)[0]
                            type = node.localName

                        toReturn.append(self.__parse(node, type))
                    return toReturn

            # parse a complex or primitive type and return it
            type = data[0].localName
            return self.__parse(data[0], type)
        elif hasattr(replytype, 'typecode'):
            tc = replytype.typecode
        else:
            tc = replytype
        return self.ps.Parse(tc)
Example #5
0
class ParsedSoap:
    '''A Parsed SOAP object.
        Convert the text to a DOM tree and parse SOAP elements.
        Instance data:
            reader -- the DOM reader
            dom -- the DOM object
            ns_cache -- dictionary (by id(node)) of namespace dictionaries
            id_cache -- dictionary (by XML ID attr) of elements
            envelope -- the node holding the SOAP Envelope
            header -- the node holding the SOAP Header (or None)
            body -- the node holding the SOAP Body
            body_root -- the serialization root in the SOAP Body
            data_elements -- list of non-root elements in the SOAP Body
            trailer_elements -- list of elements following the SOAP body
    '''
    defaultReaderClass = DefaultReader

    def __init__(self,
                 input,
                 readerclass=None,
                 keepdom=False,
                 trailers=False,
                 resolver=None,
                 envelope=True,
                 **kw):
        '''Initialize.
        Keyword arguments:
            trailers -- allow trailer elments (default is zero)
            resolver -- function (bound method) to resolve URI's
            readerclass -- factory class to create a reader
            keepdom -- do not release the DOM
            envelope -- look for a SOAP envelope.
        '''

        self.readerclass = readerclass
        self.keepdom = keepdom
        if not self.readerclass:
            self.readerclass = self.defaultReaderClass

        try:
            self.reader = self.readerclass()
            if type(input) in _stringtypes:
                self.dom = self.reader.fromString(input)
            else:
                self.dom = self.reader.fromStream(input)
        except Exception, e:
            # Is this in the header?  Your guess is as good as mine.
            #raise ParseException("Can't parse document (" + \
            #    str(e.__class__) + "): " + str(e), 0)
            raise

        self.ns_cache = {
            id(self.dom): {
                'xml': XMLNS.XML,
                'xmlns': XMLNS.BASE,
                '': ''
            }
        }
        self.trailers, self.resolver, self.id_cache = trailers, resolver, {}

        # Exactly one child element
        c = [
            E for E in _children(self.dom) if E.nodeType == _Node.ELEMENT_NODE
        ]
        if len(c) == 0:
            raise ParseException("Document has no Envelope", 0)
        if len(c) != 1:
            raise ParseException("Document has extra child elements", 0)

        if envelope is False:
            self.body_root = c[0]
            return

        # And that one child must be the Envelope
        elt = c[0]
        if elt.localName != "Envelope" \
        or elt.namespaceURI != SOAP.ENV:
            raise ParseException('Document has "' + elt.localName + \
                '" element, not Envelope', 0)
        self._check_for_legal_children("Envelope", elt)
        for a in _attrs(elt):
            name = a.nodeName
            if name.find(":") == -1 and name not in ["xmlns", "id"]:
                raise ParseException('Unqualified attribute "' + \
                        name + '" in Envelope', 0)
        self.envelope = elt
        if not _valid_encoding(self.envelope):
            raise ParseException("Envelope has invalid encoding", 0)

        # Get Envelope's child elements.
        c = [
            E for E in _children(self.envelope)
            if E.nodeType == _Node.ELEMENT_NODE
        ]
        if len(c) == 0:
            raise ParseException("Envelope is empty (no Body)", 0)

        # Envelope's first child might be the header; if so, nip it off.
        elt = c[0]
        if elt.localName == "Header" \
        and elt.namespaceURI == SOAP.ENV:
            self._check_for_legal_children("Header", elt)
            self._check_for_pi_nodes(_children(elt), 1)
            self.header = c.pop(0)
            self.header_elements = _child_elements(self.header)
        else:
            self.header, self.header_elements = None, []

        # Now the first child must be the body
        if len(c) == 0:
            raise ParseException("Envelope has header but no Body", 0)
        elt = c.pop(0)
        if elt.localName != "Body" \
        or elt.namespaceURI != SOAP.ENV:
            if self.header:
                raise ParseException('Header followed by "' + \
                        elt.localName + \
                        '" element, not Body', 0, elt, self.dom)
            else:
                raise ParseException('Document has "' + \
                        elt.localName + \
                        '" element, not Body', 0, elt, self.dom)
        self._check_for_legal_children("Body", elt, 0)
        self._check_for_pi_nodes(_children(elt), 0)
        self.body = elt
        if not _valid_encoding(self.body):
            raise ParseException("Body has invalid encoding", 0)

        # Trailer elements.
        if not self.trailers:
            if len(c):
                raise ParseException("Element found after Body", 0, elt,
                                     self.dom)
            # Don't set self.trailer_elements = []; if user didn't ask
            # for trailers we *want* to throw an exception.
        else:
            self.trailer_elements = c
            for elt in self.trailer_elements:
                if not elt.namespaceURI:
                    raise ParseException('Unqualified trailer element', 0, elt,
                                         self.dom)

        # Find the serialization root.  Divide the Body children into
        # root (root=1), no (root=0), maybe (no root attribute).
        self.body_root, no, maybe = None, [], []
        for elt in _child_elements(self.body):
            root = _find_root(elt)
            if root == "1":
                if self.body_root:
                    raise ParseException("Multiple seralization roots found",
                                         0, elt, self.dom)
                self.body_root = elt
            elif root == "0":
                no.append(elt)
            elif not root:
                maybe.append(elt)
            else:
                raise ParseException('Illegal value for root attribute', 0,
                                     elt, self.dom)

        # If we didn't find a root, get the first one that didn't
        # say "not me", unless they all said "not me."
        if self.body_root is None:
            if len(maybe):
                self.body_root = maybe[0]
            else:
                raise ParseException('No serialization root found', 0,
                                     self.body, self.dom)
        if not _valid_encoding(self.body_root):
            raise ParseException("Invalid encoding", 0, elt, self.dom)

        # Now get all the non-roots (in order!).
        rootid = id(self.body_root)
        self.data_elements = [
            E for E in _child_elements(self.body) if id(E) != rootid
        ]
        self._check_for_pi_nodes(self.data_elements, 0)
Example #6
0
    def __init__(
        self,
        input,
        readerclass=None,
        keepdom=False,
        trailers=False,
        resolver=None,
        envelope=True,
        **kw
        ):
        '''Initialize.
        Keyword arguments:
            trailers -- allow trailer elments (default is zero)
            resolver -- function (bound method) to resolve URI's
            readerclass -- factory class to create a reader
            keepdom -- do not release the DOM
            envelope -- look for a SOAP envelope.
        '''

        self.readerclass = readerclass
        self.keepdom = keepdom
        if not self.readerclass:
            self.readerclass = self.defaultReaderClass

        try:
            self.reader = self.readerclass()
            if type(input) in _stringtypes:
                self.dom = self.reader.fromString(input)
            else:
                self.dom = self.reader.fromStream(input)
        except Exception:

            # Is this in the header?  Your guess is as good as mine.
            # raise ParseException("Can't parse document (" + \
            #    str(e.__class__) + "): " + str(e), 0)

            raise

        self.ns_cache = {id(self.dom): {'xml': XMLNS.XML,
                         'xmlns': XMLNS.BASE, '': ''}}

        (self.trailers, self.resolver, self.id_cache) = (trailers,
                resolver, {})

        # Exactly one child element

        c = [E for E in _children(self.dom) if E.nodeType
             == _Node.ELEMENT_NODE]
        if len(c) == 0:
            raise ParseException('Document has no Envelope', 0)
        if len(c) != 1:
            raise ParseException('Document has extra child elements', 0)

        if envelope is False:
            self.body_root = c[0]
            return

        # And that one child must be the Envelope

        elt = c[0]
        if elt.localName != 'Envelope' or elt.namespaceURI not in (SOAP.ENV, SOAP.ENV12):
            raise ParseException('Document has %r element, not %s' %
                                 ((elt.namespaceURI, elt.localName), (SOAP.ENV12, 'Envelope')), 0)
        self._check_for_legal_children('Envelope', elt)
        for a in _attrs(elt):
            name = a.nodeName
            if name.find(':') == -1 and name not in ['xmlns', 'id']:
                raise ParseException('Unqualified attribute "' + name
                        + '" in Envelope', 0)
        self.envelope = elt
        if not _valid_encoding(self.envelope):
            raise ParseException('Envelope has invalid encoding', 0)

        # Get Envelope's child elements.

        c = [E for E in _children(self.envelope) if E.nodeType
             == _Node.ELEMENT_NODE]
        if len(c) == 0:
            raise ParseException('Envelope is empty (no Body)', 0)

        # Envelope's first child might be the header; if so, nip it off.

        elt = c[0]
        if elt.localName == 'Header' and elt.namespaceURI in (SOAP.ENV, SOAP.ENV12):
            self._check_for_legal_children('Header', elt)
            self._check_for_pi_nodes(_children(elt), 1)
            self.header = c.pop(0)
            self.header_elements = _child_elements(self.header)
        else:
            (self.header, self.header_elements) = (None, [])

        # Now the first child must be the body

        if len(c) == 0:
            raise ParseException('Envelope has header but no Body', 0)
        elt = c.pop(0)
        if elt.localName != 'Body' or elt.namespaceURI not in (SOAP.ENV, SOAP.ENV12):
            if self.header:
                raise ParseException('Header followed by "%r" element, not Body' % ((elt.namespaceURI, elt.localName),), 0,
                        elt, self.dom)
            else:
                raise ParseException('Document has "%r element, not Body' % ((elt.namespaceURI, elt.localName),), 0, elt, self.dom)
        self._check_for_legal_children('Body', elt, 0)
        self._check_for_pi_nodes(_children(elt), 0)
        self.body = elt
        if not _valid_encoding(self.body):
            raise ParseException('Body has invalid encoding', 0)

        # Trailer elements.

        if not self.trailers:
            if len(c):
                raise ParseException('Element found after Body', 0,
                        elt, self.dom)
        else:

            # Don't set self.trailer_elements = []; if user didn't ask
            # for trailers we *want* to throw an exception.

            self.trailer_elements = c
            for elt in self.trailer_elements:
                if not elt.namespaceURI:
                    raise ParseException('Unqualified trailer element',
                            0, elt, self.dom)

        # Find the serialization root.  Divide the Body children into
        # root (root=1), no (root=0), maybe (no root attribute).

        (self.body_root, no, maybe) = (None, [], [])
        for elt in _child_elements(self.body):
            root = _find_root(elt)
            if root == '1':
                if self.body_root:
                    raise ParseException('Multiple seralization roots found'
                            , 0, elt, self.dom)
                self.body_root = elt
            elif root == '0':
                no.append(elt)
            elif not root:
                maybe.append(elt)
            else:
                raise ParseException('Illegal value for root attribute'
                        , 0, elt, self.dom)

        # If we didn't find a root, get the first one that didn't
        # say "not me", unless they all said "not me."

        if self.body_root is None:
            if len(maybe):
                self.body_root = maybe[0]
            else:
                raise ParseException('No serialization root found', 0,
                        self.body, self.dom)
        if not _valid_encoding(self.body_root):
            raise ParseException('Invalid encoding', 0, elt, self.dom)

        # Now get all the non-roots (in order!).

        rootid = id(self.body_root)
        self.data_elements = [E for E in _child_elements(self.body)
                              if id(E) != rootid]
        self._check_for_pi_nodes(self.data_elements, 0)
Example #7
0
    def __init__(self, input, readerclass=None, keepdom=False, trailers=False, resolver=None, envelope=True, **kw):
        """Initialize.
        Keyword arguments:
            trailers -- allow trailer elments (default is zero)
            resolver -- function (bound method) to resolve URI's
            readerclass -- factory class to create a reader
            keepdom -- do not release the DOM
            envelope -- look for a SOAP envelope.
        """

        self.readerclass = readerclass
        self.keepdom = keepdom
        if not self.readerclass:
            if self.defaultReaderClass != None:
                self.readerclass = self.defaultReaderClass
            else:
                from xml.dom.ext.reader import PyExpat

                self.readerclass = PyExpat.Reader
        try:
            self.reader = self.readerclass()
            if type(input) in _stringtypes:
                self.dom = self.reader.fromString(input)
            else:
                self.dom = self.reader.fromStream(input)
        except Exception as e:
            # Is this in the header?  Your guess is as good as mine.
            # raise ParseException("Can't parse document (" + \
            #    str(e.__class__) + "): " + str(e), 0)
            raise

        self.ns_cache = {id(self.dom): {"xml": XMLNS.XML, "xmlns": XMLNS.BASE, "": ""}}
        self.trailers, self.resolver, self.id_cache = trailers, resolver, {}

        # Exactly one child element
        c = [E for E in _children(self.dom) if E.nodeType == _Node.ELEMENT_NODE]
        if len(c) == 0:
            raise ParseException("Document has no Envelope", 0)
        if len(c) != 1:
            raise ParseException("Document has extra child elements", 0)

        if envelope is False:
            self.body_root = c[0]
            return

        # And that one child must be the Envelope
        elt = c[0]
        if elt.localName != "Envelope" or elt.namespaceURI != SOAP.ENV:
            raise ParseException('Document has "' + elt.localName + '" element, not Envelope', 0)
        self._check_for_legal_children("Envelope", elt)
        for a in _attrs(elt):
            name = a.nodeName
            if name.find(":") == -1 and name not in ["xmlns", "id"]:
                raise ParseException('Unqualified attribute "' + name + '" in Envelope', 0)
        self.envelope = elt
        if not _valid_encoding(self.envelope):
            raise ParseException("Envelope has invalid encoding", 0)

        # Get Envelope's child elements.
        c = [E for E in _children(self.envelope) if E.nodeType == _Node.ELEMENT_NODE]
        if len(c) == 0:
            raise ParseException("Envelope is empty (no Body)", 0)

        # Envelope's first child might be the header; if so, nip it off.
        elt = c[0]
        if elt.localName == "Header" and elt.namespaceURI == SOAP.ENV:
            self._check_for_legal_children("Header", elt)
            self._check_for_pi_nodes(_children(elt), 1)
            self.header = c.pop(0)
            self.header_elements = _child_elements(self.header)
        else:
            self.header, self.header_elements = None, []

        # Now the first child must be the body
        if len(c) == 0:
            raise ParseException("Envelope has header but no Body", 0)
        elt = c.pop(0)
        if elt.localName != "Body" or elt.namespaceURI != SOAP.ENV:
            if self.header:
                raise ParseException('Header followed by "' + elt.localName + '" element, not Body', 0, elt, self.dom)
            else:
                raise ParseException('Document has "' + elt.localName + '" element, not Body', 0, elt, self.dom)
        self._check_for_legal_children("Body", elt, 0)
        self._check_for_pi_nodes(_children(elt), 0)
        self.body = elt
        if not _valid_encoding(self.body):
            raise ParseException("Body has invalid encoding", 0)

        # Trailer elements.
        if not self.trailers:
            if len(c):
                raise ParseException("Element found after Body", 0, elt, self.dom)
            # Don't set self.trailer_elements = []; if user didn't ask
            # for trailers we *want* to throw an exception.
        else:
            self.trailer_elements = c
            for elt in self.trailer_elements:
                if not elt.namespaceURI:
                    raise ParseException("Unqualified trailer element", 0, elt, self.dom)

        # Find the serialization root.  Divide the Body children into
        # root (root=1), no (root=0), maybe (no root attribute).
        self.body_root, no, maybe = None, [], []
        for elt in _child_elements(self.body):
            root = _find_root(elt)
            if root == "1":
                if self.body_root:
                    raise ParseException("Multiple seralization roots found", 0, elt, self.dom)
                self.body_root = elt
            elif root == "0":
                no.append(elt)
            elif not root:
                maybe.append(elt)
            else:
                raise ParseException("Illegal value for root attribute", 0, elt, self.dom)

        # If we didn't find a root, get the first one that didn't
        # say "not me", unless they all said "not me."
        if self.body_root is None:
            if len(maybe):
                self.body_root = maybe[0]
            else:
                raise ParseException("No serialization root found", 0, self.body, self.dom)
        if not _valid_encoding(self.body_root):
            raise ParseException("Invalid encoding", 0, elt, self.dom)

        # Now get all the non-roots (in order!).
        rootid = id(self.body_root)
        self.data_elements = [E for E in _child_elements(self.body) if id(E) != rootid]
        self._check_for_pi_nodes(self.data_elements, 0)
Example #8
0
    def _do_element(self, node, initial_other_attrs = []):
        '''_do_element(self, node, initial_other_attrs = []) -> None
        Process an element (and its children).'''

        # Get state (from the stack) make local copies.
        #       ns_parent -- NS declarations in parent
        #       ns_rendered -- NS nodes rendered by ancestors
        #       xml_attrs -- Attributes in XML namespace from parent
        #       ns_local -- NS declarations relevant to this element
        ns_parent, ns_rendered, xml_attrs = \
                self.state[0], self.state[1][:], self.state[2][:]
        ns_local = ns_parent.copy()

        # Divide attributes into NS, XML, and others.
        other_attrs = initial_other_attrs[:]
        in_subset = _in_subset(self.subset, node)
        for a in _attrs(node):
            if a.namespaceURI == XMLNS.BASE:
                n = a.nodeName
                if n == "xmlns:": n = "xmlns"        # DOM bug workaround
                ns_local[n] = a.nodeValue
            elif a.namespaceURI == XMLNS.XML:
                if self.unsuppressedPrefixes is None or in_subset:
                    xml_attrs.append(a)
            else:
                other_attrs.append(a)

        # Render the node
        W, name = self.write, None
        if in_subset:
            name = node.nodeName
            W('<')
            W(name)

            # Create list of NS attributes to render.
            ns_to_render = []
            for n,v in ns_local.items():
                pval = ns_parent.get(n)

                # If default namespace is XMLNS.BASE or empty, skip
                if n == "xmlns" \
                and v in [ XMLNS.BASE, '' ] and pval in [ XMLNS.BASE, '' ]:
                    continue

                # "omit namespace node with local name xml, which defines
                # the xml prefix, if its string value is
                # http://www.w3.org/XML/1998/namespace."
                if n == "xmlns:xml" \
                and v in [ 'http://www.w3.org/XML/1998/namespace' ]:
                    continue

                # If different from parent, or parent didn't render
                # and if not exclusive, or this prefix is needed or
                # not suppressed
                if (v != pval or n not in ns_rendered) \
                  and (self.unsuppressedPrefixes is None or \
                  _utilized(n, node, other_attrs, self.unsuppressedPrefixes)):
                    ns_to_render.append((n, v))

            # Sort and render the ns, marking what was rendered.
            ns_to_render.sort(_sorter_ns)
            for n,v in ns_to_render:
                self._do_attr(n, v)
                ns_rendered.append(n)

            # Add in the XML attributes (don't pass to children, since
            # we're rendering them), sort, and render.
            other_attrs.extend(xml_attrs)
            xml_attrs = []
            other_attrs.sort(_sorter)
            for a in other_attrs:
                self._do_attr(a.nodeName, a.value)
            W('>')

        # Push state, recurse, pop state.
        state, self.state = self.state, (ns_local, ns_rendered, xml_attrs)
        for c in _children(node):
            _implementation.handlers[c.nodeType](self, c)
        self.state = state

        if name: W('</%s>' % name)