C#XmlReader子节点30GB文件导入SQL Server

本文关键字:SQL Server 导入 文件 子节点 30GB C#XmlReader | 更新日期: 2023-09-27 18:24:30

数据示例:

<?xml version='1.0' encoding='UTF-8'?><osm version="0.6" generator="osmconvert 0.7P" timestamp="2013-07-20T19:00:02Z">
.
   <way id="128725988" version="1" timestamp="2011-09-03T08:06:56Z" changeset="9198624" uid="42429" user="42429">
      <nd ref="1421727256"/>
      <nd ref="1421727264"/>
      <nd ref="1421727238"/>
      <nd ref="1421727237"/>
      <nd ref="1421727256"/>
      <tag k="addr:housenumber" v="43"/>
      <tag k="addr:street" v="Wilhelm-Ahrens-Straße"/>
      <tag k="building" v="yes"/>
   </way>
.
.
   <node id="1964468590" lat="53.068416" lon="8.779039" version="1" timestamp="2012-10-14T12:29:02Z" changeset="13491909" uid="715371" user="cracklinrain"/>
   <node id="1964468593" lat="53.0684177" lon="8.7798644" version="1" timestamp="2012-10-14T12:29:02Z" changeset="13491909" uid="715371" user="cracklinrain">
      <tag k="natural" v="tree"/>
   </node>
.
.
.
   <way id="128725989" version="1" timestamp="2011-09-03T08:06:57Z" changeset="9198624" uid="42429" user="42429">
      <nd ref="1421728028"/>
      <nd ref="1421728023"/>
      <nd ref="1421728016"/>
      <nd ref="1421728024"/>
      <nd ref="1421728028"/>
      <tag k="addr:housenumber" v="44"/>
      <tag k="addr:street" v="Alma-Rogge-Straße"/>
      <tag k="building" v="yes"/>
   </way>
.
.

这是一个Xml文件的示例,其中包含30GB的数据量。

我想做的是只得到<tag>元素,它包含特定的所需元素,如addr:housenumber

需要保持连接的一件事是来自父元素的id

我的主要问题是如何处理一个30GB的文档。如果它大约是几百MB,我自己解决它就没有问题了。

我已经尝试过的:

  1. XmlReader

    对于获取特定属性非常有效,但与父id的连接丢失。

  2. 像xDocument、XmlDocument。。。

    问题在于数据量。(30 GB)
    在将~1GB加载到内存后,获得一个OutOfMemoryException
    我知道将30GB的内存加载到内存中会很疯狂。

我已经有了一个单独的工作解决方案,通过对pbf文件使用OpenSource库(但我想处理干净的数据),并通过迭代每个节点来提取所需的数据,并使用LinqToSql将其添加到数据库中。

最终结果:

我想将每条街道、门牌号、邮政编码和城市导入SQL Server数据库,其中StreetTableCityTable相连(我的第一个解决方案运行良好,但在处理了10000个项目后,它变得非常慢。)

我希望我想做的事情可以理解。

C#XmlReader子节点30GB文件导入SQL Server

我不确定,但这些链接可能会有所帮助:

https://wiki.openstreetmap.org/wiki/Osmconvert#Dispose_of_Ways_and_Relations_and_Convert_them_to_Nodes

https://wiki.openstreetmap.org/wiki/Osmconvert#Writing_CSV_Files

也有用:锇过滤器,渗透

osmconvert和osmfilter的一些选项需要一个严格有序的输入文件:首先是所有节点,然后是所有方式,然后是全部关系。在可达组内,数据应按id进行排序。

如果使用.o5m(或者.pbf)文件格式,转换和过滤会更快。

我对C#没有任何经验,但由于XML文件很大,只需读取/访问一次就足够了,因此一个简单的XML SAX解析器似乎就足够了。C#的XmlReader似乎类似于SAX解析器。因此,只要读取<node><way>元素并触发相应的事件,就只需存储id属性。无论何时读取<tag>事件并触发相应的事件,都可以将其所有属性分配给以前读取的id