diff --git a/overpy/__init__.py b/overpy/__init__.py index 13de583..377c28d 100644 --- a/overpy/__init__.py +++ b/overpy/__init__.py @@ -349,23 +349,39 @@ def from_json(cls, data, api=None): return result @classmethod - def from_xml(cls, data, api=None, parser=XML_PARSER_SAX): + def from_xml(cls, data, api=None, parser=None): """ - Create a new instance and load data from xml object. + Create a new instance and load data from xml data or object. + + .. note:: + If parser is set to None, the functions tries to find the best parse. + By default the SAX parser is chosen if a string is provided as data. + The parser is set to DOM if an xml.etree.ElementTree.Element is provided as data value. :param data: Root element - :type data: xml.etree.ElementTree.Element - :param api: + :type data: str | xml.etree.ElementTree.Element + :param api: The instance to query additional information if required. :type api: Overpass - :param parser: Specify the parser to use(DOM or SAX) - :type parser: Integer + :param parser: Specify the parser to use(DOM or SAX)(Default: None = autodetect, defaults to SAX) + :type parser: Integer | None :return: New instance of Result object :rtype: Result """ + if parser is None: + if isinstance(data, str): + parser = XML_PARSER_SAX + else: + parser = XML_PARSER_DOM + result = cls(api=api) if parser == XML_PARSER_DOM: import xml.etree.ElementTree as ET - root = ET.fromstring(data) + if isinstance(data, str): + root = ET.fromstring(data) + elif isinstance(data, ET.Element): + root = data + else: + raise exception.OverPyException("Unable to detect data type.") for elem_cls in [Node, Way, Relation, Area]: for child in root: diff --git a/tests/test_xml.py b/tests/test_xml.py index d81f003..e414ad4 100644 --- a/tests/test_xml.py +++ b/tests/test_xml.py @@ -171,6 +171,28 @@ def test_way_missing_data(self): overpy.Way.from_xml(node) +class TestParser(BaseTestNodes): + def test_exception(self): + with pytest.raises(overpy.exception.OverPyException): + overpy.Result.from_xml(123) + + def test_xml_element(self): + import xml.etree.ElementTree as ET + data = read_file("xml/node-01.xml") + root = ET.fromstring(data) + result = overpy.Result.from_xml(root) + + assert isinstance(result, overpy.Result) + self._test_node01(result) + + def test_xml_autodetect_parser(self): + data = read_file("xml/node-01.xml") + result = overpy.Result.from_xml(data) + + assert isinstance(result, overpy.Result) + self._test_node01(result) + + class TestRemark(object): def test_remark_runtime_error(self): api = overpy.Overpass()