Skip to content

Commit

Permalink
Refactor XML subelement list handling in fastkml.helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
cleder committed Dec 22, 2023
1 parent 1d17e0f commit 0981d68
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 85 deletions.
31 changes: 13 additions & 18 deletions fastkml/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
from fastkml.geometry import Point
from fastkml.geometry import Polygon
from fastkml.helpers import xml_subelement_list
from fastkml.helpers import xml_subelement_list_kwarg
from fastkml.helpers import xml_subelement_list_kwarg_iterable
from fastkml.styles import Style
from fastkml.styles import StyleMap
from fastkml.styles import StyleUrl
Expand Down Expand Up @@ -156,21 +156,16 @@ def _get_kwargs(
kwargs["features"] = []
name_spaces = kwargs["name_spaces"]
assert name_spaces is not None
for klass in (
Folder,
Placemark,
Document,
):
kwargs["features"].extend(
xml_subelement_list_kwarg(
element=element,
ns=ns,
name_spaces=name_spaces,
kwarg="features",
obj_class=klass,
strict=strict,
).get("features", []),
)
kwargs.update(
xml_subelement_list_kwarg_iterable(
element=element,
ns=ns,
name_spaces=name_spaces,
kwarg="features",
obj_classes=(Folder, Placemark, Document),
strict=strict,
),
)
return kwargs


Expand Down Expand Up @@ -275,12 +270,12 @@ def _get_kwargs(
name_spaces = kwargs["name_spaces"]
assert name_spaces is not None
kwargs.update(
xml_subelement_list_kwarg(
xml_subelement_list_kwarg_iterable(
element=element,
ns=ns,
name_spaces=name_spaces,
kwarg="schemata",
obj_class=Schema,
obj_classes=(Schema,),
strict=strict,
),
)
Expand Down
21 changes: 5 additions & 16 deletions fastkml/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
from fastkml.helpers import subelement_text_kwarg
from fastkml.helpers import text_subelement
from fastkml.helpers import xml_subelement_list
from fastkml.helpers import xml_subelement_list_kwarg
from fastkml.helpers import xml_subelement_list_kwarg_iterable
from fastkml.types import Element

__all__ = [
Expand Down Expand Up @@ -410,26 +410,15 @@ def _get_kwargs(
)
name_spaces = kwargs["name_spaces"]
assert name_spaces is not None
kwargs["elements"] = []
kwargs["elements"].extend(
xml_subelement_list_kwarg(
element=element,
ns=ns,
name_spaces=name_spaces,
kwarg="elements",
obj_class=Data,
strict=strict,
).get("elements", []),
)
kwargs["elements"].extend(
xml_subelement_list_kwarg(
kwargs.update(
xml_subelement_list_kwarg_iterable(
element=element,
ns=ns,
name_spaces=name_spaces,
kwarg="elements",
obj_class=SchemaData,
obj_classes=(Data, SchemaData),
strict=strict,
).get("elements", []),
),
)

return kwargs
19 changes: 5 additions & 14 deletions fastkml/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
from fastkml.helpers import xml_subelement
from fastkml.helpers import xml_subelement_kwarg
from fastkml.helpers import xml_subelement_list
from fastkml.helpers import xml_subelement_list_kwarg
from fastkml.helpers import xml_subelement_list_kwarg_iterable
from fastkml.links import Link
from fastkml.mixins import TimeMixin
from fastkml.styles import Style
Expand Down Expand Up @@ -390,25 +390,16 @@ def _get_kwargs(
)
name_spaces = kwargs["name_spaces"]
assert name_spaces is not None
kwargs["styles"] = xml_subelement_list_kwarg(
element=element,
ns=ns,
name_spaces=name_spaces,
kwarg="styles",
obj_class=Style,
strict=strict,
).get("styles", [])
kwargs["styles"].extend(
xml_subelement_list_kwarg(
kwargs.update(
xml_subelement_list_kwarg_iterable(
element=element,
ns=ns,
name_spaces=name_spaces,
kwarg="styles",
obj_class=StyleMap,
obj_classes=(Style, StyleMap),
strict=strict,
).get("styles", []),
),
)

kwargs.update(
xml_subelement_kwarg(
element=element,
Expand Down
6 changes: 3 additions & 3 deletions fastkml/gx.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
from fastkml.helpers import bool_subelement
from fastkml.helpers import subelement_bool_kwarg
from fastkml.helpers import xml_subelement_list
from fastkml.helpers import xml_subelement_list_kwarg
from fastkml.helpers import xml_subelement_list_kwarg_iterable
from fastkml.types import Element

__all__ = [
Expand Down Expand Up @@ -395,12 +395,12 @@ def _get_kwargs(
),
)
kwargs.update(
xml_subelement_list_kwarg(
xml_subelement_list_kwarg_iterable(
element=element,
ns=name_spaces["gx"],
name_spaces=name_spaces,
kwarg="tracks",
obj_class=Track,
obj_classes=(Track,),
strict=strict,
),
)
Expand Down
27 changes: 27 additions & 0 deletions fastkml/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from typing import Dict
from typing import List
from typing import Optional
from typing import Tuple
from typing import Type

from fastkml import config
Expand Down Expand Up @@ -283,3 +284,29 @@ def xml_subelement_list_kwarg(
}
else:
return {}


def xml_subelement_list_kwarg_iterable(
*,
element: Element,
ns: str,
name_spaces: Dict[str, str],
kwarg: str,
obj_classes: Tuple[Type[_XMLObject], ...],
strict: bool,
) -> Dict[str, List[_XMLObject]]:
args_list = []
for obj_class in obj_classes:
if subelements := element.findall(f"{ns}{obj_class.get_tag_name()}"):
args_list.extend(
[
obj_class.class_from_element(
ns=ns,
name_spaces=name_spaces,
element=subelement,
strict=strict,
)
for subelement in subelements
],
)
return {kwarg: args_list}
23 changes: 11 additions & 12 deletions fastkml/kml.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
from fastkml.enums import Verbosity
from fastkml.features import Placemark
from fastkml.helpers import xml_subelement_list
from fastkml.helpers import xml_subelement_list_kwarg
from fastkml.helpers import xml_subelement_list_kwarg_iterable
from fastkml.overlays import GroundOverlay
from fastkml.overlays import PhotoOverlay
from fastkml.types import Element
Expand Down Expand Up @@ -127,17 +127,16 @@ def _get_kwargs(
name_spaces = kwargs["name_spaces"]
assert name_spaces is not None
kwargs["features"] = []
for klass in (Document, Folder, Placemark, GroundOverlay, PhotoOverlay):
kwargs["features"].extend(
xml_subelement_list_kwarg(
element=element,
ns=ns,
name_spaces=name_spaces,
kwarg="features",
obj_class=klass,
strict=strict,
).get("features", []),
)
kwargs.update(
xml_subelement_list_kwarg_iterable(
element=element,
ns=ns,
name_spaces=name_spaces,
kwarg="features",
obj_classes=(Document, Folder, Placemark, GroundOverlay, PhotoOverlay),
strict=strict,
),
)
return kwargs

@classmethod
Expand Down
29 changes: 13 additions & 16 deletions fastkml/styles.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
from fastkml.helpers import xml_subelement
from fastkml.helpers import xml_subelement_kwarg
from fastkml.helpers import xml_subelement_list
from fastkml.helpers import xml_subelement_list_kwarg
from fastkml.helpers import xml_subelement_list_kwarg_iterable
from fastkml.types import Element

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -1003,19 +1003,16 @@ def _get_kwargs(
name_spaces = kwargs["name_spaces"]
assert name_spaces is not None

kwargs["styles"] = []
for style in [BalloonStyle, IconStyle, LabelStyle, LineStyle, PolyStyle]:
kwargs["styles"].extend(
xml_subelement_list_kwarg(
element=element,
ns=ns,
name_spaces=name_spaces,
kwarg="styles",
obj_class=style,
strict=strict,
).get("styles", []),
)

kwargs.update(
xml_subelement_list_kwarg_iterable(
element=element,
ns=ns,
name_spaces=name_spaces,
kwarg="styles",
obj_classes=(BalloonStyle, IconStyle, LabelStyle, LineStyle, PolyStyle),
strict=strict,
),
)
return kwargs


Expand Down Expand Up @@ -1199,12 +1196,12 @@ def _get_kwargs(
name_spaces = kwargs["name_spaces"]
assert name_spaces is not None
kwargs.update(
xml_subelement_list_kwarg(
xml_subelement_list_kwarg_iterable(
element=element,
ns=ns,
name_spaces=name_spaces,
kwarg="pairs",
obj_class=Pair,
obj_classes=(Pair,),
strict=strict,
),
)
Expand Down
14 changes: 9 additions & 5 deletions tests/data_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,13 @@ def test_schema(self) -> None:
assert s.simple_fields[0] == field
s.simple_fields = []
assert not s.simple_fields
fields = {"type": "int", "name": "Integer", "display_name": "An Integer"}
s.simple_fields = (data.SimpleField(**fields),)
assert s.simple_fields[0] == data.SimpleField(**fields)
fields = {
"type": DataType.int_,
"name": "Integer",
"display_name": "An Integer",
}
s.simple_fields = [data.SimpleField(**fields)] # type: ignore[arg-type]
assert s.simple_fields[0] == data.SimpleField(**fields) # type: ignore[arg-type]

def test_schema_from_string(self) -> None:
doc = """<Schema name="TrailHeadType" id="TrailHeadTypeId">
Expand Down Expand Up @@ -104,10 +108,10 @@ def test_schema_data(self) -> None:
assert len(sd.data) == 2
assert sd.data[0] == data.SimpleData(value="Some Text", name="text")
assert sd.data[1] == data.SimpleData(value=1, name="Integer")
new_data = (
new_data = [
data.SimpleData("text", "Some new Text"),
data.SimpleData(value=2, name="Integer"),
)
]
sd.data = new_data
assert len(sd.data) == 2
assert sd.data[0].name == "text"
Expand Down
2 changes: 1 addition & 1 deletion tests/gx_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ def test_track_from_str(self) -> None:
class TestMultiTrack(StdLibrary):
def test_from_multilinestring(self) -> None:
lines = geo.MultiLineString(
([(0, 0), (1, 1), (1, 2), (2, 2)], [[0.0, 0.0], [1.0, 2.0]]),
(((0, 0), (1, 1), (1, 2), (2, 2)), ((0.0, 0.0), (1.0, 2.0))),
)

mt = MultiTrack(geometry=lines, ns="")
Expand Down

0 comments on commit 0981d68

Please sign in to comment.