You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求可将含几何数据的XML导入PostgreSQL的实用XSLT

用XSLT处理XML几何数据导入PostgreSQL

刚好做过类似的需求,我来给你一步步拆解怎么实现!核心思路是把XML里的几何结构转换成PostgreSQL(配合PostGIS)支持的WKT格式,再生成可执行的SQL脚本完成导入。

第一步:先明确XML结构示例

先给个典型的XML片段,方便对应理解:

<PSKs>
  <PSK>
    <ID>1</ID>
    <GEOMETRY>
      <P>
        <B S="10.0$20.0"/>
      </P>
    </GEOMETRY>
  </PSK>
  <PSK>
    <ID>2</ID>
    <GEOMETRY>
      <L>
        <B S="10.0$20.0$30.0$40.0$50.0$60.0"/>
      </L>
    </GEOMETRY>
  </PSK>
  <PSK>
    <ID>3</ID>
    <GEOMETRY>
      <MP>
        <B S="10.0$20.0"/>
        <B S="30.0$40.0"/>
        <B S="50.0$60.0"/>
      </MP>
    </GEOMETRY>
  </PSK>
</PSKs>

这里我先做个类型对应假设(你可以根据实际业务调整):

  • <P> → Point(单点)
  • <L> → LineString(线)
  • <MP> → MultiPoint(多点)

第二步:编写XSLT转换脚本

用XSLT 2.0(支持tokenize函数,处理字符串分割更顺手),脚本会自动把XML转换成PostgreSQL可执行的SQL:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" encoding="UTF-8"/>

  <!-- 主入口:生成建表SQL + 所有INSERT语句 -->
  <xsl:template match="/">
    <!-- 先启用PostGIS扩展(如果没装的话) -->
    <xsl:text>CREATE EXTENSION IF NOT EXISTS postgis;</xsl:text>
    <xsl:text>&#10;</xsl:text>
    <!-- 创建存储表 -->
    <xsl:text>CREATE TABLE IF NOT EXISTS psk_data (id INT PRIMARY KEY, geom GEOMETRY);</xsl:text>
    <xsl:text>&#10;</xsl:text>

    <!-- 遍历每个PSK节点生成插入语句 -->
    <xsl:for-each select="PSKs/PSK">
      <xsl:variable name="psk-id" select="ID"/>
      <xsl:variable name="wkt-geom">
        <xsl:apply-templates select="GEOMETRY/*"/>
      </xsl:variable>

      <!-- 生成INSERT,用ST_GeomFromText把WKT转成PostGIS几何对象 -->
      <xsl:text>INSERT INTO psk_data (id, geom) VALUES (</xsl:text>
      <xsl:value-of select="$psk-id"/>
      <xsl:text>, ST_GeomFromText('</xsl:text>
      <xsl:value-of select="$wkt-geom"/>
      <xsl:text>', 4326));</xsl:text> <!-- 4326是WGS84坐标系,按需修改 -->
      <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
  </xsl:template>

  <!-- 处理Point类型(<P>节点) -->
  <xsl:template match="P">
    <xsl:variable name="coords" select="tokenize(B/@S, '\$')"/>
    <xsl:text>Point(</xsl:text>
    <xsl:value-of select="$coords[1]"/> <!-- X坐标 -->
    <xsl:text> </xsl:text>
    <xsl:value-of select="$coords[2]"/> <!-- Y坐标 -->
    <xsl:text>)</xsl:text>
  </xsl:template>

  <!-- 处理LineString类型(<L>节点) -->
  <xsl:template match="L">
    <xsl:variable name="coord-list" select="tokenize(B/@S, '\$')"/>
    <xsl:text>LineString(</xsl:text>
    <!-- 每两个坐标一组,生成x y格式 -->
    <xsl:for-each select="$coord-list[position() mod 2 = 1]">
      <xsl:if test="position() > 1">, </xsl:if>
      <xsl:value-of select="."/>
      <xsl:text> </xsl:text>
      <xsl:value-of select="$coord-list[position() + current()/position()]"/>
    </xsl:for-each>
    <xsl:text>)</xsl:text>
  </xsl:template>

  <!-- 处理MultiPoint类型(<MP>节点) -->
  <xsl:template match="MP">
    <xsl:text>MultiPoint(</xsl:text>
    <xsl:for-each select="B">
      <xsl:if test="position() > 1">, </xsl:if>
      <xsl:variable name="coords" select="tokenize(@S, '\$')"/>
      <xsl:text>(</xsl:text>
      <xsl:value-of select="$coords[1]"/>
      <xsl:text> </xsl:text>
      <xsl:value-of select="$coords[2]"/>
      <xsl:text>)</xsl:text>
    </xsl:for-each>
    <xsl:text>)</xsl:text>
  </xsl:template>

</xsl:stylesheet>

第三步:执行转换并导入

1. 把XML转换成SQL脚本

用XSLT处理器(比如免费的Saxon HE版本)执行转换:

java -jar saxon9he.jar -s:你的输入文件.xml -xsl:上面的XSLT文件.xsl -o:output.sql

如果用其他处理器(比如Xalan),命令逻辑类似,调整参数即可。

2. 导入到PostgreSQL

确保你的数据库已经启用PostGIS,然后执行生成的SQL:

psql -d 你的数据库名 -U 用户名 -f output.sql

可选调整点

  • 如果<MP>实际是MultiPolygon:修改<MP>的模板,每个<B>对应多边形的环,WKT格式要写成MultiPolygon(((x1 y1, x2 y2, ..., x1 y1)))(注意闭合)
  • 坐标顺序如果是Y/X:调整模板里$coords[1]和$coords[2]的顺序
  • 大数据量优化:可以生成CSV格式代替SQL,用COPY命令导入,效率更高(需要调整XSLT输出为CSV,注意WKT的引号处理)

内容的提问来源于stack exchange,提问作者ondrusu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:05:55