Home > Blockchain >  How to take specific values from xml and convert them to GeoJSON
How to take specific values from xml and convert them to GeoJSON

Time:06-23

I am trying to convert an xml file to a GeoJSON file using xsltproc and an xsl file. To do so, we are trying to convert the xml file and the xsl files. What I want to do is get the 22203-bldg-562 of the gen:value in the xml and put it in the id with-param. I would like to put it in the with-param of the id. But when I do the conversion, I get the following error. I think I have the wrong way to access `gen:value'. I don't know how to access gen:value. What should I do?

$ xsltproc style.xsl 52383622_bldg_6697_op.gml > index.geojson
XPath error : Undefined namespace prefix
xmlXPathEval: 1 object left on the stack

xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:core="http://www.opengis.net/citygml/2.0" xmlns:bldg="http://www.opengis.net/citygml/building/2.0"
                xmlns:gml="http://www.opengis.net/gml" xmlns:str="http://exslt.org/strings" extension-element-prefixes="str">
    <xsl:output method="text" indent="no" encoding="UTF-8" />


    <xsl:template match="/">
        <xsl:apply-templates select="/core:CityModel/core:cityObjectMember/bldg:Building" />
    </xsl:template>


    <xsl:template match="bldg:Building" />


    <xsl:template match="bldg:Building[bldg:lod0FootPrint][bldg:measuredHeight]">
        <xsl:apply-templates select="bldg:lod0FootPrint//gml:Polygon">
            <xsl:with-param name="z" select="number(bldg:measuredHeight)" />
        </xsl:apply-templates>
    </xsl:template>


    <xsl:template match="bldg:Building[bldg:lod0RoofEdge][bldg:measuredHeight]">
        <xsl:apply-templates select="bldg:lod0RoofEdge//gml:Polygon">
            <xsl:with-param name="z" select="number(bldg:measuredHeight)" />
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="bldg:Building[gen:stringAttribute]">
        <xsl:apply-templates select="bldg:lod0RoofEdge//gml:Polygon">
            <xsl:with-param name="id" select="string(gen:value)" />
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="gml:Polygon">
        <xsl:param name="z" />
        <xsl:param name="id" />
        <xsl:text>{"type":"Feature","properties":{"z":</xsl:text>
        <xsl:value-of select="$z" />
        <xsl:text>, "buildingId": </xsl:text>
        <xsl:value-of select="$id" />
        <xsl:text>},<xsl:text>
        <xsl:text>"geometry":{"type":"Polygon","coordinates":[</xsl:text>
        <xsl:for-each select=".//gml:posList">
            <xsl:if test="position()!=1">,</xsl:if>
            <xsl:text>[</xsl:text>
            <xsl:variable name="t" select="str:split(.)" />
            <xsl:for-each select="$t[position() mod 3 = 1]">
                <xsl:variable name="i" select="position()" />
                <xsl:if test="$i != 1">,</xsl:if>
                <xsl:value-of select="concat('[',$t[$i*3-1],',',string(.),']')" />
            </xsl:for-each>
            <xsl:text>]</xsl:text>
        </xsl:for-each>
        <xsl:text>]}}&#10;</xsl:text>
    </xsl:template>
</xsl:stylesheet>

xml

<?xml version="1.0" encoding="UTF-8"?>
<core:CityModel xmlns:grp="http://www.opengis.net/citygml/cityobjectgroup/2.0" xmlns:core="http://www.opengis.net/citygml/2.0" xmlns:pbase="http://www.opengis.net/citygml/profiles/base/2.0" xmlns:smil20lang="http://www.w3.org/2001/SMIL20/Language" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:smil20="http://www.w3.org/2001/SMIL20/" xmlns:bldg="http://www.opengis.net/citygml/building/2.0" xmlns:xAL="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0" xmlns:uro="http://www.kantei.go.jp/jp/singi/tiiki/toshisaisei/itoshisaisei/iur/uro/1.4" xmlns:luse="http://www.opengis.net/citygml/landuse/2.0" xmlns:app="http://www.opengis.net/citygml/appearance/2.0" xmlns:gen="http://www.opengis.net/citygml/generics/2.0" xmlns:dem="http://www.opengis.net/citygml/relief/2.0" xmlns:tex="http://www.opengis.net/citygml/texturedsurface/2.0" xmlns:tun="http://www.opengis.net/citygml/tunnel/2.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sch="http://www.ascc.net/xml/schematron" xmlns:veg="http://www.opengis.net/citygml/vegetation/2.0" xmlns:frn="http://www.opengis.net/citygml/cityfurniture/2.0" xmlns:gml="http://www.opengis.net/gml" xmlns:tran="http://www.opengis.net/citygml/transportation/2.0" xmlns:wtr="http://www.opengis.net/citygml/waterbody/2.0" xmlns:brid="http://www.opengis.net/citygml/bridge/2.0" xsi:schemaLocation="http://www.kantei.go.jp/jp/singi/tiiki/toshisaisei/itoshisaisei/iur/uro/1.4 http://www.kantei.go.jp/jp/singi/tiiki/toshisaisei/itoshisaisei/iur/schemas/uro/1.4/urbanObject.xsd http://www.opengis.net/citygml/2.0 http://schemas.opengis.net/citygml/2.0/cityGMLBase.xsd http://www.opengis.net/citygml/landuse/2.0 http://schemas.opengis.net/citygml/landuse/2.0/landUse.xsd http://www.opengis.net/citygml/building/2.0 http://schemas.opengis.net/citygml/building/2.0/building.xsd http://www.opengis.net/citygml/transportation/2.0 http://schemas.opengis.net/citygml/transportation/2.0/transportation.xsd http://www.opengis.net/citygml/generics/2.0 http://schemas.opengis.net/citygml/generics/2.0/generics.xsd http://www.opengis.net/citygml/cityobjectgroup/2.0 http://schemas.opengis.net/citygml/cityobjectgroup/2.0/cityObjectGroup.xsd http://www.opengis.net/gml http://schemas.opengis.net/gml/3.1.1/base/gml.xsd http://www.opengis.net/citygml/appearance/2.0 http://schemas.opengis.net/citygml/appearance/2.0/appearance.xsd">
    <gml:boundedBy>
        <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/6697" srsDimension="3">
            <gml:lowerCorner>34.93876102525376 138.77691876113923 100.941</gml:lowerCorner>
            <gml:upperCorner>34.940826513994075 138.77930957077407 146.745</gml:upperCorner>
        </gml:Envelope>
    </gml:boundedBy>
    <core:cityObjectMember>
        <bldg:Building gml:id="BLD_5b633bbe-eee5-4070-8e1b-202b0c8645da">
            <gen:stringAttribute name="建物ID">
                <gen:value>22203-bldg-562</gen:value> // this <gen:value>
            </gen:stringAttribute>
            <gen:genericAttributeSet name="土砂災害警戒区域">
                <gen:stringAttribute name="区域区分">
                    <gen:value>1</gen:value>
                </gen:stringAttribute>
                <gen:stringAttribute name="現象区分">
                    <gen:value>2</gen:value>
                </gen:stringAttribute>
            </gen:genericAttributeSet>
            <bldg:class codeSpace="../../codelists/Building_class.xml">3001</bldg:class>
            <bldg:measuredHeight uom="m">3.0</bldg:measuredHeight>
            <bldg:lod0RoofEdge>
                <gml:MultiSurface>
                    <gml:surfaceMember>
                        <gml:Polygon>
                            <gml:exterior>
                                <gml:LinearRing>
                                    <gml:posList>34.939526582609396 138.77809852668528 126.612 34.93950339425915 138.77803651940917 126.612 34.93947843686556 138.77805028353634 126.612 34.939488015045036 138.77807589974992 126.612 34.93944985234779 138.77809694303997 126.612 34.939448517348794 138.77809335876165 126.612 34.93944036670756 138.77809785248826 126.612 34.93946410156609 138.7781613285196 126.612 34.93948566512662 138.77814943590874 126.612 34.93947687539607 138.7781259461289 126.612 34.939526582609396 138.77809852668528 126.612</gml:posList>
                                </gml:LinearRing>
                            </gml:exterior>
                        </gml:Polygon>
・
・
・

CodePudding user response:

If you want to use the gen prefix in your stylesheet, then you need to add the namespace declaration xmlns:gen="http://www.opengis.net/citygml/generics/2.0" to your stylesheet.

Note also, xsl:template does not allow an xsl:with-param child.

CodePudding user response:

I've had success with this xsl.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:core="http://www.opengis.net/citygml/2.0" xmlns:bldg="http://www.opengis.net/citygml/building/2.0" xmlns:gen="http://www.opengis.net/citygml/generics/2.0"
                xmlns:gml="http://www.opengis.net/gml" xmlns:str="http://exslt.org/strings" extension-element-prefixes="str">
    <xsl:output method="text" indent="no" encoding="UTF-8" />
    
    
    <xsl:template match="/">
        <xsl:apply-templates select="/core:CityModel/core:cityObjectMember/bldg:Building" />
    </xsl:template>
    
    
    <xsl:template match="bldg:Building" />
    
    
    <xsl:template match="bldg:Building[bldg:lod0FootPrint][bldg:measuredHeight][gen:stringAttribute]">
        <xsl:apply-templates select="bldg:lod0FootPrint//gml:Polygon">
            <xsl:with-param name="z" select="number(bldg:measuredHeight)" />
            <xsl:with-param name="id" select="string(gen:stringAttribute)" />
        </xsl:apply-templates>
    </xsl:template>
    
    
    <xsl:template match="bldg:Building[bldg:lod0RoofEdge][bldg:measuredHeight][gen:stringAttribute]">
        <xsl:apply-templates select="bldg:lod0RoofEdge//gml:Polygon">
            <xsl:with-param name="z" select="number(bldg:measuredHeight)" />
            <xsl:with-param name="id" select="string(gen:stringAttribute//gen:value)" />
        </xsl:apply-templates>
    </xsl:template>



    <xsl:template match="gml:Polygon">
        <xsl:param name="z" />
        <xsl:param name="id" />
        <xsl:text>{"type":"Feature","properties":{"z":</xsl:text>
        <xsl:value-of select="$z" />
        <xsl:text>, "buildingId": "</xsl:text>
        <xsl:value-of select="$id" />
        <xsl:text>"},</xsl:text>
        <xsl:text>"geometry":{"type":"Polygon","coordinates":[</xsl:text>
        <xsl:for-each select=".//gml:posList">
            <xsl:if test="position()!=1">,</xsl:if>
            <xsl:text>[</xsl:text>
            <xsl:variable name="t" select="str:split(.)" />
            <xsl:for-each select="$t[position() mod 3 = 1]">
                <xsl:variable name="i" select="position()" />
                <xsl:if test="$i != 1">,</xsl:if>
                <xsl:value-of select="concat('[',$t[$i*3-1],',',string(.),']')" />
            </xsl:for-each>
            <xsl:text>]</xsl:text>
        </xsl:for-each>
        <xsl:text>]}}&#10;</xsl:text>
    </xsl:template>
</xsl:stylesheet>
  • Related