通过 xsl 转换将 xml 数据中的米转换为英尺
Convert meters to foot in xml data via xsl transformation
我想通过将一些值 (tag@v) 从米转换为英尺来修改我的 xml 文件。我是 xml 的新手,这对你们中的一个人来说应该没有问题。
公式是:1米是3.2808英尺
我想转换node/tag@v if node/tag@k="ele"的属性值。
任何人都可以 post 给我整个 xsl 吗?
提前谢谢你。
<?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>
我的目标是获得一个 xml 文件,其中包含计算出的 "tag@v" 值,例如:
<?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>
我已经开始使用 xslt,但我不知道如何使它正确。
<?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>
您的方法存在几个问题。例如,而不是:
<node><xsl:value-of select="node"/></node>
创建空的 node
元素(因为你的 node
元素 是 空的),你应该使用类似的东西:
<node><xsl:copy-of select="@*"/></node>
而不是:
<xsl:for-each select="/tag">
什么都不选择,因为 tag
不是 /
根节点的子节点,您应该选择作为当前节点子节点的 tag
元素:
<xsl:for-each select="./tag">
可以缩短为:
<xsl:for-each select="tag">
但是,与其继续沿着这条路走下去,我建议你采用一个更好的整体策略:使用 identity transform 模板复制所有节点作为规则,然后添加一个与要修改的属性匹配的模板作为例外:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tag[@k='ele']/@v">
<xsl:attribute name="v">
<xsl:value-of select="round(. * 3.28084)" />
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
我想通过将一些值 (tag@v) 从米转换为英尺来修改我的 xml 文件。我是 xml 的新手,这对你们中的一个人来说应该没有问题。 公式是:1米是3.2808英尺 我想转换node/tag@v if node/tag@k="ele"的属性值。 任何人都可以 post 给我整个 xsl 吗? 提前谢谢你。
<?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>
我的目标是获得一个 xml 文件,其中包含计算出的 "tag@v" 值,例如:
<?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>
我已经开始使用 xslt,但我不知道如何使它正确。
<?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>
您的方法存在几个问题。例如,而不是:
<node><xsl:value-of select="node"/></node>
创建空的 node
元素(因为你的 node
元素 是 空的),你应该使用类似的东西:
<node><xsl:copy-of select="@*"/></node>
而不是:
<xsl:for-each select="/tag">
什么都不选择,因为 tag
不是 /
根节点的子节点,您应该选择作为当前节点子节点的 tag
元素:
<xsl:for-each select="./tag">
可以缩短为:
<xsl:for-each select="tag">
但是,与其继续沿着这条路走下去,我建议你采用一个更好的整体策略:使用 identity transform 模板复制所有节点作为规则,然后添加一个与要修改的属性匹配的模板作为例外:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tag[@k='ele']/@v">
<xsl:attribute name="v">
<xsl:value-of select="round(. * 3.28084)" />
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>