SSMS :: 从 OSM 导入 XML 文件并解析节点
SSMS :: import XML file from OSM and parse nodes
我正在尝试将 .osm
文件(基本上是 XML
文件)导入 SQL 服务器。
如果您愿意,可以通过下载我正在从 here 导入的文件的副本来尝试代码(只需单击 "Export")。我尝试解析的 XML 文件如下所示:
<node id="335558025" visible="true" version="9" changeset="56753970" timestamp="2018-02-28T12:01:28Z" user="SimonPoole" uid="92387" lat="46.5116200" lon="6.6254900">
<tag k="addr:city" v="Lausanne"/>
<tag k="addr:country" v="CH"/>
<tag k="addr:postcode" v="1007"/>
<tag k="amenity" v="car_sharing"/>
<tag k="capacity" v="1"/>
<tag k="mobility:station_id" v="3053"/>
<tag k="name" v="Lausanne Harpe / Av. F. C. de la Harpe"/>
<tag k="opening_hours" v="24/7"/>
<tag k="operator" v="Mobility Genossenschaft"/>
<tag k="source" v="http://www.mobility.ch/"/>
<tag k="website" v="http://www.mobility.ch/"/>
这是我的代码:
DECLARE @TableName as NVARCHAR(35) = 'OSM_' -- declare table name
DECLARE @x xml;
SET @x = (SELECT * FROM OPENROWSET(
BULK 'C:\Users\franc\Desktop\Lausanne.osm', -- Import file here
SINGLE_BLOB) AS x);
Select @x
DROP TABLE IF EXISTS dbo. #TempTable -- drop temp table if exist
EXEC('DROP TABLE IF EXISTS dbo.' + @TableName) -- drop table if exist
CREATE TABLE #TempTable (
[id] NUMERIC NULL,
[visible] CHAR(5) NULL,
[version] NUMERIC NULL,
[changeset] NUMERIC NULL,
[timestamp] NVARCHAR(25) NULL,
[user] NVARCHAR(50) NULL,
[uid] NUMERIC NULL,
[lat] FLOAT NULL,
[lon] FLOAT NULL,
[amenity] NVARCHAR(50) NULL
)
INSERT INTO #TempTable -- Insert data into table
SELECT
id = OSMnode.value('@id', 'NUMERIC'),
visible = OSMnode.value('@visible', 'CHAR(5)'),
[version] = OSMnode.value('@version', 'NUMERIC'),
changeset = OSMnode.value('@changeset', 'NUMERIC'),
[timestamp] = OSMnode.value('@timestamp', 'NVARCHAR(25)'),
[user] = OSMnode.value('@user', 'NVARCHAR(50)'),
[uid] = OSMnode.value('@uid', 'NUMERIC'),
latitude = OSMnode.value('@lat', 'FLOAT'),
longitude = OSMnode.value('@lon', 'FLOAT'),
amenity = OSMnode.value('(tag[@amenity="k"])[1]', 'NVARCHAR(50)')
FROM
@x.nodes('/osm/node') AS OSM(OSMnode);
DECLARE @sql AS NVARCHAR(1000)
SET @sql = 'SELECT * INTO ' + @TableName + ' FROM #TempTable'
EXEC (@sql)
EXEC('SELECT * FROM ' + @TableName)
DROP TABLE IF EXISTS dbo. #TempTable
工作得很好,但我无法导入列 "Amenity",它一直导致 NULL
:
所以整个问题都在这一行:
amenity = OSMnode.value('(tag[@amenity="k"])[1]', 'NVARCHAR(50)')
如何解析该值?
谢谢
您的 XPath 表达式 tag[@amenity="k"]
正在过滤 <tag amenity="k">
。您需要将其更改为 tag[@k="amenity"]
。
这是一个示例,另外 returns v
属性的值,我假设您正在寻找...
declare @x xml =
N'<node id="335558025" visible="true" version="9" changeset="56753970" timestamp="2018-02-28T12:01:28Z" user="SimonPoole" uid="92387" lat="46.5116200" lon="6.6254900">
<tag k="amenity" v="car_sharing"/>
</node>';
select
id = OSMnode.value('@id', 'NUMERIC'),
amenity = OSMnode.value('(tag[@k="amenity"]/@v)[1]', 'NVARCHAR(50)')
from @x.nodes('//node') as OSM(OSMnode);
产生...
id amenity
335558025 car_sharing
我正在尝试将 .osm
文件(基本上是 XML
文件)导入 SQL 服务器。
如果您愿意,可以通过下载我正在从 here 导入的文件的副本来尝试代码(只需单击 "Export")。我尝试解析的 XML 文件如下所示:
<node id="335558025" visible="true" version="9" changeset="56753970" timestamp="2018-02-28T12:01:28Z" user="SimonPoole" uid="92387" lat="46.5116200" lon="6.6254900">
<tag k="addr:city" v="Lausanne"/>
<tag k="addr:country" v="CH"/>
<tag k="addr:postcode" v="1007"/>
<tag k="amenity" v="car_sharing"/>
<tag k="capacity" v="1"/>
<tag k="mobility:station_id" v="3053"/>
<tag k="name" v="Lausanne Harpe / Av. F. C. de la Harpe"/>
<tag k="opening_hours" v="24/7"/>
<tag k="operator" v="Mobility Genossenschaft"/>
<tag k="source" v="http://www.mobility.ch/"/>
<tag k="website" v="http://www.mobility.ch/"/>
这是我的代码:
DECLARE @TableName as NVARCHAR(35) = 'OSM_' -- declare table name
DECLARE @x xml;
SET @x = (SELECT * FROM OPENROWSET(
BULK 'C:\Users\franc\Desktop\Lausanne.osm', -- Import file here
SINGLE_BLOB) AS x);
Select @x
DROP TABLE IF EXISTS dbo. #TempTable -- drop temp table if exist
EXEC('DROP TABLE IF EXISTS dbo.' + @TableName) -- drop table if exist
CREATE TABLE #TempTable (
[id] NUMERIC NULL,
[visible] CHAR(5) NULL,
[version] NUMERIC NULL,
[changeset] NUMERIC NULL,
[timestamp] NVARCHAR(25) NULL,
[user] NVARCHAR(50) NULL,
[uid] NUMERIC NULL,
[lat] FLOAT NULL,
[lon] FLOAT NULL,
[amenity] NVARCHAR(50) NULL
)
INSERT INTO #TempTable -- Insert data into table
SELECT
id = OSMnode.value('@id', 'NUMERIC'),
visible = OSMnode.value('@visible', 'CHAR(5)'),
[version] = OSMnode.value('@version', 'NUMERIC'),
changeset = OSMnode.value('@changeset', 'NUMERIC'),
[timestamp] = OSMnode.value('@timestamp', 'NVARCHAR(25)'),
[user] = OSMnode.value('@user', 'NVARCHAR(50)'),
[uid] = OSMnode.value('@uid', 'NUMERIC'),
latitude = OSMnode.value('@lat', 'FLOAT'),
longitude = OSMnode.value('@lon', 'FLOAT'),
amenity = OSMnode.value('(tag[@amenity="k"])[1]', 'NVARCHAR(50)')
FROM
@x.nodes('/osm/node') AS OSM(OSMnode);
DECLARE @sql AS NVARCHAR(1000)
SET @sql = 'SELECT * INTO ' + @TableName + ' FROM #TempTable'
EXEC (@sql)
EXEC('SELECT * FROM ' + @TableName)
DROP TABLE IF EXISTS dbo. #TempTable
工作得很好,但我无法导入列 "Amenity",它一直导致 NULL
:
所以整个问题都在这一行:
amenity = OSMnode.value('(tag[@amenity="k"])[1]', 'NVARCHAR(50)')
如何解析该值?
谢谢
您的 XPath 表达式 tag[@amenity="k"]
正在过滤 <tag amenity="k">
。您需要将其更改为 tag[@k="amenity"]
。
这是一个示例,另外 returns v
属性的值,我假设您正在寻找...
declare @x xml =
N'<node id="335558025" visible="true" version="9" changeset="56753970" timestamp="2018-02-28T12:01:28Z" user="SimonPoole" uid="92387" lat="46.5116200" lon="6.6254900">
<tag k="amenity" v="car_sharing"/>
</node>';
select
id = OSMnode.value('@id', 'NUMERIC'),
amenity = OSMnode.value('(tag[@k="amenity"]/@v)[1]', 'NVARCHAR(50)')
from @x.nodes('//node') as OSM(OSMnode);
产生...
id amenity
335558025 car_sharing