def fromstring(cls, request, xml_str, strip=None):
        """Parse XML text contained in string and return as an XGResponse
        object for the given request type.

        Arguments:
            request   - XGRequest object
            xml_str   - string containing XML response to parse

        Returns:
            XGResponse object

        """

        root_el = ET.fromstring(xml_str)

        if root_el.tag != "xg-response":
            raise ParseError("Not xg-response")
        else:
            xg_resp_el = root_el.getchildren()[0]
            if xg_resp_el.tag == "xg-status":
                # parse xg-status
                for child in xg_resp_el.getchildren():
                    if child.tag == "status-msg":
                        r_msg = child.text
                    elif child.tag == "status-code":
                        r_code = child.text
                    else:
                        raise ParseError("Unknown status field.")

                # Handle authentication via Exception
                if r_msg == "Not authenticated":
                    raise AuthenticationError(r_msg)

                return XGResponse("status", int(r_code), r_msg)

            elif xg_resp_el.tag != "%s-response" % (request.type):
                raise ParseError("Response type mismatch.")

            # Parse response

            # TODO(gfreeman):  Refactor to not use find() ... loop through once
            ret_status_el = xg_resp_el.find("return-status")
            if ret_status_el is None:
                raise ParseError("Missing return-status field.")

            try:
                r_code = ret_status_el.find("return-code").text
            except AttributeError:
                raise ParseError("Missing return-code field.")

            try:
                r_msg = ret_status_el.find("return-msg").text
            except AttributeError:
                r_msg = ""

            try:
                db_rev = xg_resp_el.find("db-revision-id").text
                if not db_rev.isdigit():
                    raise ParseError("Non-numeric db-revision-id")
            except AttributeError:
                db_rev = "0"

            try:
                nodes_el = xg_resp_el.find("nodes")
            except AttributeError:
                raise ParseError("Missing nodes element.")

            #
            # Parse the return nodes per parameters in XGRequest
            #
            # If request.flat is True, we return a dict of nodes
            # keyed to node_name. If a returned node had no name
            # it will not be included.
            #
            # If request.flat is False, we return a LIST of nodes
            # that can contain subnodes.
            #
            # If values_only is True, we return node values rather
            # than XGNode objects.
            #

            nodes_d = {}
            nodes_l = []

            if nodes_el is not None:
                for node in nodes_el.getchildren():
                    # parse node
                    if node.tag != "node":
                        raise ParseError("Unexpected subelement '%s'"
                                         % (node.tag,))

                    if request.flat:
                        nodes_d.update(XGNode.parse_el(node, request.flat,
                                       strip=strip))
                    else:
                        nodes_l.append(XGNode.parse_el(node, request.flat,
                                       strip=strip))

            if request.flat:
                nodes = XGNodeDict(nodes_d, request.values_only)
            else:
                nodes = nodes_l

            return XGResponse(request.type, int(r_code), r_msg, db_rev, nodes)
Exemple #2
0
    def fromstring(cls, request, xml_str, strip=None):
        """
        Parse XML text contained in string and return as an XGResponse
        object for the given request type.

        Arguments:
            request   - XGRequest object
            xml_str   - string containing XML response to parse

        Returns:
            XGResponse object

        """

        root_el = ET.fromstring(xml_str)

        if root_el.tag != "xg-response":
            raise ParseError("Not xg-response")
        else:
            xg_resp_el = root_el.getchildren()[0]
            if xg_resp_el.tag == "xg-status":
                # parse xg-status
                for child in xg_resp_el.getchildren():
                    if child.tag == "status-msg":
                        r_msg = child.text
                    elif child.tag == "status-code":
                        r_code = child.text
                    else:
                        raise ParseError("Unknown status field.")

                # Handle authentication via Exception
                if r_msg == "Not authenticated":
                    raise AuthenticationError(r_msg)

                return XGResponse("status", int(r_code), r_msg)

            elif xg_resp_el.tag != "%s-response" % (request.type):
                raise ParseError("Response type mismatch.")

            # Parse response

            # TODO(gfreeman):  Refactor to not use find() ... loop through once
            ret_status_el = xg_resp_el.find("return-status")
            if ret_status_el is None:
                raise ParseError("Missing return-status field.")

            try:
                r_code = ret_status_el.find("return-code").text
            except AttributeError:
                raise ParseError("Missing return-code field.")

            try:
                r_msg = ret_status_el.find("return-msg").text
            except AttributeError:
                r_msg = ""

            try:
                db_rev = xg_resp_el.find("db-revision-id").text
                if not db_rev.isdigit():
                    raise ParseError("Non-numeric db-revision-id")
            except AttributeError:
                db_rev = "0"

            try:
                nodes_el = xg_resp_el.find("nodes")
            except AttributeError:
                raise ParseError("Missing nodes element.")

            #
            # Parse the return nodes per parameters in XGRequest
            #
            # If request.flat is True, we return a dict of nodes
            # keyed to node_name. If a returned node had no name
            # it will not be included.
            #
            # If request.flat is False, we return a LIST of nodes
            # that can contain subnodes.
            #
            # If values_only is True, we return node values rather
            # than XGNode objects.
            #

            nodes_d = {}
            nodes_l = []

            if nodes_el is not None:
                for node in nodes_el.getchildren():
                    # parse node
                    if node.tag != "node":
                        raise ParseError("Unexpected subelement '%s'" %
                                         (node.tag, ))

                    if request.flat:
                        nodes_d.update(
                            XGNode.parse_el(node, request.flat, strip=strip))
                    else:
                        nodes_l.append(
                            XGNode.parse_el(node, request.flat, strip=strip))

            if request.flat:
                nodes = XGNodeDict(nodes_d, request.values_only)
            else:
                nodes = nodes_l

            return XGResponse(request.type, int(r_code), r_msg, db_rev, nodes)