An OpenStreetMap xml document is composed (among other things) of a set of “node” elements and a set of “way” elements.
The “node” elements can (optionally) nest “tag” elements.
The “way” elements are composed by an ordered list of “node” elements, referenced by the nested elements “nd”, with their attribute “ref” pointing to the attribute “id” at the “node” elements.
Here an example:
<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="CGImap 0.0.2">
<node id="1726631203" lat="50.8500083" lon="4.3553223" visible="true" version="6" changeset="9938190" timestamp="2011-11-24T22:05:32Z"/>
...
<way id="160611697" user="toSc" uid="246723" visible="true" version="1" changeset="11385198" timestamp="2012-04-22T14:57:19Z">
<nd ref="1726631203"/>
<nd ref="1726631223"/>
<nd ref="1726631213"/>
<nd ref="1726631205"/>
<nd ref="1726631185"/>
<nd ref="1726631203"/>
</way>
...
</osm>
My question is how, using XSLT, could I do the following transformation ?
- Filtering all the node elements that are not referenced by any way element.
- Filtering the way elements that reference node elements not included in the source xml document.
- Changing the attribute “visible” to “false”, to any “node” element not having “tag” children elements.
Any other elements should remain in the generated xml.
This transformation fullfills all three requirements:
when applied on this XML document (suitably created to contain a case for each requirement):
the wanted, correct result (all filterings are performed and the
visibleattribute of one of thenodeelements is turned tofalse) is produced:Explanation:
The identity rule is overriden by three templates, each implementing one of the three requirements.
The two overriding templates that have empty bodies implement the two filtering requirements.
We are using keys to conveniently and efficiently find
nodes by theiridattribute andnds by theirrefattribute.The attribute value replacement requirement is implemented in the third overriding template.