Esempio n. 1
0
 def test_attribute_name(self):
     attribute_xpath = XPath('./element/@attri')
     absolute_attribute_xpath = XPath('/ns:root/nss:element/@nss:attribute')
     element_xpath = XPath('/root/element/subelement')
     with self.subTest():
         self.assertEqual(attribute_xpath.attribute_name(), 'attri')
     with self.subTest():
         self.assertEqual(absolute_attribute_xpath.attribute_name(), 'nss:attribute')
     with self.subTest():
         with self.assertRaises(ValueError):
             element_xpath.attribute_name()
Esempio n. 2
0
 def test_node_xpaths(self):
     root = etree.fromstring(sample_no_namespace)
     xml_tree = etree.ElementTree(root)
     xpath_set = {XPath('/catalog/book[1]'),
                  XPath('/catalog/book[1]/@id'), XPath('/catalog/book[1]/author'), XPath('/catalog/book[1]/title'), XPath('/catalog/book[1]/genre'),
                  XPath('/catalog/book[1]/price'), XPath('/catalog/book[1]/publish_date'), XPath('/catalog/book[1]/description'),
                  XPath('/catalog/book[2]'),
                  XPath('/catalog/book[2]/@id'), XPath('/catalog/book[2]/author'), XPath('/catalog/book[2]/title'), XPath('/catalog/book[2]/genre'),
                  XPath('/catalog/book[2]/price'), XPath('/catalog/book[2]/publish_date'), XPath('/catalog/book[2]/description')}
     with self.subTest():
         self.assertCountEqual(xpath_set, generate_node_xpaths(xml_tree))
     with self.subTest():
         self.assertSetEqual(xpath_set, set(generate_node_xpaths(xml_tree)))
Esempio n. 3
0
 def test_is_attribute(self):
     attribute_node = XPath('/root/element/@attribute')
     ns_attribute_node = XPath('/ns:root/nss:element/@nss:attribute')
     element_node = XPath('root/element')
     with self.subTest():
         self.assertTrue(attribute_node.is_attribute())
     with self.subTest():
         self.assertTrue(ns_attribute_node.is_attribute())
     with self.subTest():
         self.assertFalse(element_node.is_attribute())
Esempio n. 4
0
 def test_parent(self):
     absolute_attribute_xpath = XPath('/ns:root/nss:element/@nss:attribute')
     relative_element_xpath = XPath('./element/subelement')
     with self.subTest():
         self.assertEqual(absolute_attribute_xpath.parent(), XPath('/ns:root/nss:element'))
     with self.subTest():
         self.assertEqual(relative_element_xpath.parent(), XPath('./element'))
Esempio n. 5
0
    def test_change_attribute_tag(self):
        with self.subTest():
            xpath = XPath('/adrmsg:ADRMessage/adrmsg:hasMember/aixm:Route/@gml:id')
            reference = JSONPath('$.ADRMessage.hasMember.Route._id')
            self.assertEqual(reference, xpath.to_json_path(attributes='_', with_namespaces=False))

        with self.subTest():
            xpath = XPath('/adrmsg:ADRMessage/adrmsg:hasMember/aixm:Route/@gml:id')
            reference = JSONPath('$.ADRMessage.hasMember.Route.id')
            self.assertEqual(reference, xpath.to_json_path(attributes='', with_namespaces=False))

        with self.subTest():
            xpath = XPath('/adrmsg:ADRMessage/adrmsg:hasMember/aixm:Route/@gml:id')
            reference = JSONPath('$.adrmsg:ADRMessage.adrmsg:hasMember.aixm:Route.attrib_gml:id')
            self.assertEqual(reference, xpath.to_json_path(attributes='attrib_', with_namespaces=True))
Esempio n. 6
0
 def test_is_relative(self):
     absolute_xpath = XPath('/root/element/subelement')
     relative_xpath = XPath('./element/@attribute')
     with self.subTest():
         self.assertFalse(absolute_xpath.is_relative())
     with self.subTest():
         self.assertTrue(relative_xpath.is_relative())
Esempio n. 7
0
    def test_sequence_path(self):
        with self.subTest():
            xpath = XPath("/adrmsg:ADRMessage/adrmsg:hasMember[1]/aixm:Route/@gml:id")
            reference = JSONPath("$.adrmsg:ADRMessage.adrmsg:hasMember[0].aixm:Route._gml:id")
            self.assertEqual(reference, xpath.to_json_path(attributes="_", with_namespaces=True))

        with self.subTest():
            xpath = XPath("/adrmsg:ADRMessage/adrmsg:hasMember[1]/aixm:Route/@gml:id")
            reference = JSONPath("$.ADRMessage.hasMember[0].Route.id")
            self.assertEqual(reference, xpath.to_json_path(attributes="", with_namespaces=False))

        with self.subTest():
            xpath = XPath("/adrmsg:ADRMessage/adrmsg:hasMember[-1]/aixm:Route/@gml:id")
            reference = JSONPath("$.ADRMessage.hasMember[-1].Route.id")
            self.assertRaises(ValueError)
Esempio n. 8
0
 def test_index_removal(self):
     xpath = XPath('/root/element[10]/subelement/subsubelement[1]/@attribute')
     reference = XPath('/root/element/subelement/subsubelement/@attribute')
     with self.subTest():
         self.assertEqual(xpath.remove_indices(in_place=False), reference)
     with self.subTest():
         xpath.remove_indices(in_place=True)
         self.assertEqual(xpath, reference)
Esempio n. 9
0
 def test_namespace_substitution(self):
     xpath = XPath('/adrmsg:ADRMessage/adrmsg:hasMember[1]/aixm:Route/@{http://www.opengis.net/gml/3.2}id')
     short_xpath = XPath('/adrmsg:ADRMessage/adrmsg:hasMember[1]/aixm:Route/@gml:id')
     with self.subTest():
         self.assertEqual(short_xpath, xpath.shorten_namespaces(self.namespaces, in_place=False))
     with self.subTest():
         xpath.shorten_namespaces(self.namespaces, in_place=True)
         self.assertEqual(short_xpath, xpath)
Esempio n. 10
0
def infer_path_type(path: str) -> Union[XPath, JSONPath]:
    """
    Infers the type of a path (XPath or JSONPath) based on its syntax.
    It performs some basic sanity checks to differentiate a JSONPath from an XPath.
    :param path: A valid XPath or JSONPath string.
    :return: An instance of JSONPath or XPath
    """
    if not path:
        raise ValueError("No path given")
    if path[0] in ['$', '@']:
        return JSONPath(path)
    else:
        if path[0] in ['.', '/']:
            return XPath(path)
        else:
            raise ValueError("Couldn't identify the path type for {}".format(path))
Esempio n. 11
0
def iter_map_xml_document_to_dict(xml_document: Path,
                                  xml_namespaces: Dict = None,
                                  json: Optional[Dict] = None,
                                  ignore_empty: bool = True) -> Iterator[Union[Dict, List]]:
    """
    Generator that iteratively maps each node encountered in the input xml_document.
    It will infer the output type for each node.
    :param xml_document: A Path to the XML document that is to be converted.
    :param xml_namespaces: A dictionary defining the XML namespaces with namespace shortname as keys
                           and the full namespace name as values. Follows the xml standard library
                           convention for XML namespaces.
    :param json: An input dictionary into which the XML document is to be mapped.
                 Defaults to an empty dictionary if none given.
    :param ignore_empty: A boolean indicating if missing XML Nodes should be ignored.
    :return: Yields a json serializable dictionary or list
    """
    json = json or {}
    xml_etree = xml_parse(str(xml_document))  # type: ElementTree
    root = xml_etree.getroot()
    root_xpath = XPath(xml_etree.getpath(root))
    all_elements = xml_etree.iterfind('//*')  # type: Iterable[ElementTree]

    for element in all_elements:
        ns_map = element.nsmap
        element_path = xml_etree.getpath(element)
        element_xpath = XPath(element_path)
        element_xpath.shorten_namespaces(ns_map, in_place=True).relative_to(root_xpath, in_place=True)
        attrib_paths = (XPath(f'{element_path}/@{attrib_name}') for attrib_name, _ in element.attrib.items())

        for attrib in attrib_paths:
            attrib.shorten_namespaces(ns_map, in_place=True)
            attrib.relative_to(root_xpath, in_place=True)
            yield attrib

    for node in generate_nodes(xml_etree, xml_namespaces):
        jsonize_mapping = node.to_jsonize(attributes='_')
        node_map: XMLNodeToJSONNode = parse_node_map(jsonize_mapping, transformations=[])
        node_map.map(xml_etree, json, xml_namespaces=xml_namespaces, ignore_empty=ignore_empty)
        yield json
Esempio n. 12
0
 def test_ignore_namespaces(self):
     xpath = XPath('/adrmsg:ADRMessage/adrmsg:hasMember/aixm:Route/@gml:id')
     reference = JSONPath('$.ADRMessage.hasMember.Route.@id')
     self.assertEqual(reference, xpath.to_json_path(attributes='@', with_namespaces=False))
Esempio n. 13
0
 def test_relative_path(self):
     xpath = XPath('./adrmsg:ADRMessage/adrmsg:hasMember/aixm:Route/@gml:id')
     reference = JSONPath('@.adrmsg:ADRMessage.adrmsg:hasMember.aixm:Route.@gml:id')
     self.assertEqual(reference, xpath.to_json_path(attributes='@', with_namespaces=True))
Esempio n. 14
0
    def test_make_relative_path(self):
        with self.subTest():
            xpath = XPath('/root/element[10]/subelement/subsubelement[1]/@attribute')
            parent = XPath('/root/element[10]')
            reference = XPath('./subelement/subsubelement[1]/@attribute')
            with self.subTest():
                self.assertEqual(xpath.relative_to(parent, in_place=False), reference)
            with self.subTest():
                xpath.relative_to(parent, in_place=True)
                self.assertEqual(xpath, reference)

        with self.subTest():
            xpath = XPath('/root/element[10]/subelement/subsubelement[1]')
            parent = xpath
            reference = XPath('.')
            with self.subTest():
                self.assertEqual(xpath.relative_to(parent, in_place=False), reference)
            with self.subTest():
                xpath.relative_to(parent, in_place=True)
                self.assertEqual(xpath, reference)
Esempio n. 15
0
 def test_split(self):
     absolute_attribute_xpath = XPath('/ns:root/nss:element/@nss:attribute')
     relative_element_xpath = XPath('./element/subelement')
     with self.subTest():
         # TODO: Evaluate if the numbering convention is appropriate
         self.assertEqual(absolute_attribute_xpath.split(1), (XPath(''), XPath('./ns:root/nss:element/@nss:attribute')))
         self.assertEqual(absolute_attribute_xpath.split(2), (XPath('/ns:root'), XPath('./nss:element/@nss:attribute')))
     with self.subTest():
         self.assertEqual(relative_element_xpath.split(1), (XPath('.'), XPath('./element/subelement')))
         self.assertEqual(relative_element_xpath.split(2), (XPath('./element'), XPath('./subelement')))
     with self.subTest():
         with self.assertRaises(ValueError):
             relative_element_xpath.split(-1)
Esempio n. 16
0
    def test_descendance(self):
        with self.subTest():
            ancestor = XPath('/root/element')
            descendant = XPath('/root/element/subelement/leaf/@attribute')
            self.assertTrue(descendant.is_descendant_of(ancestor))

        with self.subTest():
            ancestor = XPath('/root/element')
            not_descendant = XPath('/root/otherElement/subelement/leaf')
            self.assertFalse(not_descendant.is_descendant_of(ancestor))

        with self.subTest():
            ancestor = XPath('/root/element')
            not_descendant = XPath('/root/elemental')
            self.assertFalse(not_descendant.is_descendant_of(ancestor))