通过xsl转换将米转换为xml数据中的英尺

时间:2015-06-15 15:47:57

标签: xml xslt openstreetmap

我想通过将一些值(标记@ v)从米转换为英尺来修改我的xml文件。我是xml的新手,对你们其中一个人来说应该没问题。 公式是:1米是3.2808英尺 如果node / tag @ k =“ele”,我想转换node / tag @ v的属性值。 任何人都可以发给我整个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>

我的目标是获取一个带有计算出的“tag @ v”值的xml文件,如:

<?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>

1 个答案:

答案 0 :(得分:1)

您的方法存在一些问题。例如,而不是:

<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"> 

但是,我建议您采用更好的整体策略,而不是沿着这条路走下去:使用身份转换模板将所有节点复制为规则,然后添加与您属性相匹配的模板想要修改为例外:

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>