GML的XML映射是将GML元素(如gml:Point、gml:Polygon、gml:featureMember)按其地理语义关联到目标模型的过程,需处理命名空间、坐标格式(gml:pos/gml:posList)、应用模式耦合及gml:id标识等关键问题。

什么是 GML 的 XML 映射
GML(Geography Markup Language)本身就是基于 XML 的地理数据编码标准,所谓“XML 映射”,实际是指将 GML 文档中的元素与地理语义(如 gml:Point、gml:Polygon、gml:featureMember)正确关联到目标模型(比如数据库表结构、对象类或 JSON Schema)。它不是 XML 解析的通用过程,而是对 GML 特定命名空间和几何/属性嵌套模式的语义识别。
解析 GML 时必须处理的命名空间问题
GML 文档几乎总带 xmlns:gml="http://www.opengis.net/gml" 及可能的版本变体(如 http://www.opengis.net/gml/3.2),不显式声明命名空间前缀,用 XPath 或 DOM 查询会直接失败。
- Python +
lxml:必须用namespaces={'gml': 'http://www.opengis.net/gml'}参数传入tree.xpath()或findall() - JavaScript(浏览器环境):
document.evaluate()需通过resolver回调返回命名空间 URI,不能只写'//gml:Point' - 常见错误现象:
find('gml:Point')返回None,但find('*')能看到节点——说明前缀未绑定,而非节点不存在
几何要素(gml:Point / gml:LineString / gml:Polygon)坐标的提取方式差异
GML 支持多种坐标表达:旧版用 gml:coordinates(已弃用),新版推荐 gml:pos(单点)或 gml:posList(多点序列),且坐标顺序默认是 lon lat(即 x y),与部分 GIS 工具的 lat lon 习惯相反。
<gml:Point>
<gml:pos>116.4 39.9</gml:pos>
</gml:Point>
<gml:Polygon>
<gml:exterior>
<gml:LinearRing>
<gml:posList>116.4 39.9 116.5 39.9 116.5 40.0 116.4 39.9</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
-
gml:pos内容直接 split() 得两个字符串,需转为 float -
gml:posList是空格分隔的扁平序列,偶数位为 x,奇数位为 y;长度必为偶数,否则数据损坏 - 若遇到
gml:coordinates decimal="." cs="," ts=" "这类老格式,cs(coordinate separator)可能是逗号,ts(tuple separator)才是空格,不能硬切空格
要素属性(gml:featureMember)与自定义应用模式(AppSchema)的耦合风险
真实 GML 文件通常包裹在应用模式(如 my:Building)中,gml:featureMember 下是业务标签而非 gml:Feature。硬编码找 gml:featureMember/* 会漏掉顶层命名空间,必须先定位具体要素类型。
- 不要写
xpath('//gml:featureMember/*'),而应查根元素或schemaLocation属性,确认业务命名空间(如xmlns:my="http://example.org/building") - 典型结构是:
<gml:featureMember><my:Building gml:id="b1">...</my:Building></gml:featureMember>,属性映射要从my:Building开始,不是从gml:featureMember - 忽略
gml:id属性会导致要素无法关联外部元数据或做增量更新——它不是可选装饰,而是 GML 要素的唯一标识锚点
真正难的不是读出坐标,而是区分哪些 gml: 标签是规范强制的,哪些是应用扩展加的,以及它们之间嵌套的语义依赖。没看 xsi:schemaLocation 就动手写映射逻辑,八成要返工。










