I would like to modify my xml file by converting some values (tag@v) from meter to foot. I am a newbie to xml and this should be no problem for one of you. The formular is: 1 meter are 3.2808 feet I want to convert the attribute value of node/tag@v if node/tag@k="ele". Can anyone post me the whole xsl? Thank you in advance.
<?xml version="1.0" encoding="utf-8"?>
<osm version="0.6">
<bounds minlat="47.8760339819708" minlon="13.5747679669094" maxlat="48.0521802776284" maxlon="14.0487569652016" origin="OSMXAPI" />
<node id="756570510" uid="-1" lat="47.9728596" lon="13.6008265">
<tag k="amenity" v="parking" />
<tag k="wheelchair" v="yes" />
</node>
<node id="756570534" uid="-1" lat="47.9728043" lon="13.6003445" />
<node id="766968743" uid="-1" lat="47.914342" lon="13.9834639" />
<node id="766972197" uid="-1" lat="47.9163063" lon="14.006467">
<tag k="fixme" v="Lage" />
<tag k="name" v="Hobelsberg" />
<tag k="natural" v="peak" />
</node>
<node id="766972201" uid="-1" lat="47.9168672" lon="14.0181185">
<tag k="ele" v="947" />
<tag k="fixme" v="Lage" />
<tag k="name" v="Kaiserkogel" />
<tag k="natural" v="peak" />
</node>
<node id="766972204" uid="-1" lat="47.9155297" lon="14.0451337">
<tag k="ele" v="1080" />
<tag k="fixme" v="Lage" />
<tag k="name" v="Pernecker Kogel" />
<tag k="natural" v="peak" />
<tag k="summit:cross" v="yes" />
</node>
</osm>
My goal is to get a xml file with the computed "tag@v" values like:
<?xml version="1.0" encoding="utf-8"?>
<osm version="0.6">
<bounds minlat="47.8760339819708" minlon="13.5747679669094" maxlat="48.0521802776284" maxlon="14.0487569652016" origin="OSMXAPI" />
<node id="756570510" uid="-1" lat="47.9728596" lon="13.6008265">
<tag k="amenity" v="parking" />
<tag k="wheelchair" v="yes" />
</node>
<node id="756570534" uid="-1" lat="47.9728043" lon="13.6003445" />
<node id="766968743" uid="-1" lat="47.914342" lon="13.9834639" />
<node id="766972197" uid="-1" lat="47.9163063" lon="14.006467">
<tag k="fixme" v="Lage" />
<tag k="name" v="Hobelsberg" />
<tag k="natural" v="peak" />
</node>
<node id="766972201" uid="-1" lat="47.9168672" lon="14.0181185">
<tag k="ele" v="3107" />
<tag k="fixme" v="Lage" />
<tag k="name" v="Kaiserkogel" />
<tag k="natural" v="peak" />
</node>
<node id="766972204" uid="-1" lat="47.9155297" lon="14.0451337">
<tag k="ele" v="3543" />
<tag k="fixme" v="Lage" />
<tag k="name" v="Pernecker Kogel" />
<tag k="natural" v="peak" />
<tag k="summit:cross" v="yes" />
</node>
</osm>
I've startet a xslt but i don't no how to make it correct.
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<osm>
<xsl:copy-of select="osm/bounds"/>
<xsl:for-each select="//node">
<node><xsl:value-of select="node"/></node>
<xsl:for-each select="/tag">
<xsl:choose>
<xsl:when test="contains(@k,'ele')">
<xsl:value-of select="round(v*3.2808)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="tag"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</osm>
</xsl:template>
</xsl:stylesheet>
There are several issues with your approach. For example, instead of:
which creates empty
node
elements (because yournode
elements are empty), you should be using something like:and instead of:
which selects nothing, because
tag
is not a child of the/
root node, you should be selecting thetag
elements that are children of the current node:which can be shortened to:
However, instead of continuing down this path, I would suggest you adopt a better overall strategy: use the identity transform template to copy all nodes as the rule, then add a template matching the attribute you want to modify as the exception:
XSLT 1.0