Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions overpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
22 changes: 22 additions & 0 deletions tests/test_xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down