def convert(self, is_collection, url, xpath, xml_string): ''' Entry for XML -> JSON conversion is_collection -- True if the results is in the collection+json format xpath -- the xpath corresponding to the query results being translated xml_string -- the XML results to translate ''' url_pieces, *_ = split_url(url) schema_root = find_child_by_path(self._schema, url_pieces) target_type = find_target_type(self._schema, url_pieces) xml_root = lxml.etree.fromstring(xml_string) elements_to_translate = xml_root.xpath(xpath) json = list() prefixes = list() is_list = schema_root.is_listy() and target_type == TargetType.List is_leaf = schema_root.is_leafy() json.append("{") if is_collection or is_list: pieces = elements_to_translate[0].tag.split("}") try: target_name = pieces[1] target_prefix = _split_namespace(schema_root.get_ns()) prefixes.append(target_prefix) except IndexError: target_name = pieces[0] target_prefix = "" if is_collection: json.append('"collection":{') json.append('"%s%s":[' % (target_prefix, target_name)) elif is_list: json.append('"%s%s":[' % (target_prefix, target_name)) for element, is_last in iterate_with_lookahead(elements_to_translate): name, prefix, prefixes = _split_tag_and_update_prefixes( element, prefixes) schema_node = schema_root if is_collection or is_list: json.append('{') elif is_leaf: pass else: json.append('"%s%s" :{' % (prefix, name)) json.append( self._translate_node(is_collection, schema_root, element, prefixes)) if not is_leaf: json.append('}') if not is_last: json.append(',') if prefix != "": prefixes.pop() if is_collection: json.append(']') json.append('}') elif is_list: json.append(']') json.append("}") return ''.join(json)
def convert(self, is_collection, url, xpath, xml_string): ''' Entry for XML -> JSON conversion is_collection -- True if the results is in the collection+json format xpath -- the xpath corresponding to the query results being translated xml_string -- the XML results to translate ''' url_pieces, *_ = split_url(url) schema_root = find_child_by_path(self._schema, url_pieces) target_type = find_target_type(self._schema, url_pieces) xml_root = lxml.etree.fromstring(xml_string) elements_to_translate = xml_root.xpath(xpath) json = list() prefixes = list() is_list = schema_root.is_listy() and target_type == TargetType.List is_leaf = schema_root.is_leafy() json.append("{") if is_collection or is_list: pieces = elements_to_translate[0].tag.split("}") try: target_name = pieces[1] target_prefix = _split_namespace(schema_root.get_ns()) prefixes.append(target_prefix) except IndexError: target_name = pieces[0] target_prefix = "" if is_collection: json.append('"collection":{') json.append('"%s%s":[' % (target_prefix, target_name)) elif is_list: json.append('"%s%s":[' % (target_prefix, target_name)) for element, is_last in iterate_with_lookahead(elements_to_translate): name, prefix, prefixes = _split_tag_and_update_prefixes(element, prefixes) schema_node = schema_root if is_collection or is_list: json.append('{') elif is_leaf: pass else: json.append('"%s%s" :{' % (prefix,name)) json.append(self._translate_node(is_collection, schema_root, element, prefixes)) if not is_leaf: json.append('}') if not is_last: json.append(',') if prefix != "": prefixes.pop() if is_collection: json.append(']') json.append('}') elif is_list: json.append(']') json.append("}") return ''.join(json)
def _translate_node(self, is_collection, schema_root, xml_node, prefixes, depth=0): ''' Translates the given XML node into JSON is_collection -- True if the results is in the collection+json format xml_node -- the current XML element to translate ''' json = list() first_child = False current_list = None current_name = schema_root.get_name() if schema_root.is_leafy(): schema_root = schema_root.get_parent() siblings = collect_siblings(xml_node) if len(siblings) == 0: if xml_node.text is None: return '"empty":""' else: return '"%s":"%s"' % (current_name, xml_node.text) for sibling_tag, is_last in iterate_with_lookahead(siblings): sib_xml_nodes = siblings[sibling_tag] child_schema_node = find_child_by_name(schema_root, sibling_tag) has_siblings = child_schema_node.is_listy() if has_siblings: sib_name, sib_prefix, prefixes = _split_tag_and_update_prefixes( sib_xml_nodes[0], prefixes) json.append('"%s%s" : [' % (sib_prefix, sib_name)) for child_xml_node, sib_is_last in iterate_with_lookahead( sib_xml_nodes): name, prefix, prefixes = _split_tag_and_update_prefixes( child_xml_node, prefixes) value = child_xml_node.text if not child_schema_node.is_leafy(): # it's a container, so iterate over children if has_siblings: json.append('{') else: json.append('"%s%s":{' % (prefix, name)) body = self._translate_node( is_collection, child_schema_node, child_xml_node, prefixes, depth + 1, ) json.append(body) json.append('}') else: if child_schema_node.node_type( ).leaf_type == RwYang.LeafType.LEAF_TYPE_EMPTY: value = "[null]" elif child_schema_node.node_type( ).leaf_type == RwYang.LeafType.LEAF_TYPE_STRING: if not value: value = '""' else: value = tornado.escape.json_encode(value) else: if not value: value = '""' else: try: float(value) except ValueError: value = tornado.escape.json_encode(value) if has_siblings: json.append('%s' % (value)) else: json.append('"%s" : %s' % (name, value)) if not sib_is_last: json.append(',') if prefix != "": prefixes.pop() if has_siblings: json.append(']') if sib_prefix != "": prefixes.pop() if not is_last: json.append(',') return ''.join(json)
def _translate_node(self, is_collection, schema_root, xml_node, prefixes, depth=0): ''' Translates the given XML node into JSON is_collection -- True if the results is in the collection+json format xml_node -- the current XML element to translate ''' json = list() first_child = False current_list = None current_name = schema_root.get_name() if schema_root.is_leafy(): schema_root = schema_root.get_parent() siblings = collect_siblings(xml_node) if len(siblings) == 0: if xml_node.text is None: return '"empty":""' else: return '"%s":"%s"' % (current_name,xml_node.text) for sibling_tag, is_last in iterate_with_lookahead(siblings): sib_xml_nodes = siblings[sibling_tag] child_schema_node = find_child_by_name(schema_root, sibling_tag) if child_schema_node is None: self._logger.warning("Unknown Child schema node <%s> for parent <%s>", sibling_tag, current_name) if is_last and json[-1] == ",": json.pop() continue has_siblings = child_schema_node.is_listy() if has_siblings: sib_name, sib_prefix, prefixes = _split_tag_and_update_prefixes(sib_xml_nodes[0], prefixes) json.append('"%s%s" : [' % (sib_prefix, sib_name)) for child_xml_node, sib_is_last in iterate_with_lookahead(sib_xml_nodes): name, prefix, prefixes = _split_tag_and_update_prefixes(child_xml_node, prefixes) value = child_xml_node.text if not child_schema_node.is_leafy(): # it's a container, so iterate over children if has_siblings: json.append('{') else: json.append('"%s%s":{' % (prefix,name)) body = self._translate_node(is_collection, child_schema_node, child_xml_node, prefixes, depth+1, ) json.append(body) json.append('}') else: if child_schema_node.node_type().leaf_type == RwYang.LeafType.LEAF_TYPE_EMPTY: value = "[null]" elif child_schema_node.node_type().leaf_type == RwYang.LeafType.LEAF_TYPE_STRING: if not value: value = '""' else: value = tornado.escape.json_encode(value) else: if not value: value = '""' else: try: float(value) except ValueError: value = tornado.escape.json_encode(value) if has_siblings: json.append('%s' % (value)) else: json.append('"%s" : %s' % (name, value)) if not sib_is_last: json.append(',') if prefix != "": prefixes.pop() if has_siblings: json.append(']') if sib_prefix != "": prefixes.pop() if not is_last: json.append(',') return ''.join(json)