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,我自己解决它就没有问题了。
我已经尝试过的:
XmlReader
对于获取特定属性非常有效,但与父id的连接丢失。
像xDocument、XmlDocument。。。
问题在于数据量。(30 GB)
在将~1GB加载到内存后,获得一个OutOfMemoryException
我知道将30GB的内存加载到内存中会很疯狂。
我已经有了一个单独的工作解决方案,通过对pbf文件使用OpenSource库(但我想处理干净的数据),并通过迭代每个节点来提取所需的数据,并使用LinqToSql将其添加到数据库中。
最终结果:
我想将每条街道、门牌号、邮政编码和城市导入SQL Server数据库,其中StreetTable
与CityTable
相连(我的第一个解决方案运行良好,但在处理了10000个项目后,它变得非常慢。)
我希望我想做的事情可以理解。
我不确定,但这些链接可能会有所帮助:
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
。