问题 将大型XML文件转换为关系数据库


我正在努力找出实现以下目标的最佳方法:

  1. 每天从第三方网站下载大型XML(1GB)文件
  2. 将该XML文件转换为我服务器上的关系数据库
  3. 添加搜索数据库的功能

对于第一部分,这是需要手动完成的事情,还是可以用cron完成?

与XML和关系数据库相关的大多数问题和答案都是指Python或PHP。这可以用javascript / nodejs完成吗?

如果这个问题更适合不同的StackExchange论坛,请告诉我,我会把它移到那里。

下面是xml代码的示例:

<case-file>
  <serial-number>123456789</serial-number>
    <transaction-date>20150101</transaction-date>
      <case-file-header>
       <filing-date>20140101</filing-date>
      </case-file-header>
      <case-file-statements>
       <case-file-statement>
        <code>AQ123</code>
        <text>Case file statement text</text>
       </case-file-statement>
       <case-file-statement>
        <code>BC345</code>
        <text>Case file statement text</text>
       </case-file-statement>
     </case-file-statements>
   <classifications>
  <classification>
   <international-code-total-no>1</international-code-total-no>
   <primary-code>025</primary-code>
  </classification>
 </classifications>
</case-file>

以下是有关如何使用这些文件的更多信息:

所有XML文件都采用相同的格式。每条记录中可能有几十个元素。这些文件每天由第三方更新(并在第三方网站上以压缩文件的形式提供)。每天的文件代表新的案例文件以及更新的案例文件。

目标是允许用户在页面上(或在生成的pdf / excel文件中)搜索信息并组织这些搜索结果。例如,用户可能希望查看包含特定单词的所有案例文件 <text> 元件。或者用户可能希望查看包含主代码025的所有案例文件(<primary-code> 元素)并且在特定日期之后提交(<filing-date> 元件)。

输入数据库的唯一数据来自XML文件 - 用户不会将任何自己的信息添加到数据库中。


6759
2017-11-13 23:00


起源

根据文件,我不认为它可以(很容易)在节点或许多PHP设置中完成;如果你真的需要解析XML,那就是大量的内存...如果你可以通过chunk(如果它是扁平的+线性的,像RSS文件)“刮”xml块,那么任何东西都可以工作。你打破一个块,解析小块,然后用新插入的行更新数据库。 - dandavis
@dandavis谢谢。通过“扁平+线性”,你的意思是不超过一个深? - Ken
本质。它是离散部分开始和结束的地方。如果标签周围有空白和可预测性,那么你可以可靠地解析它的各个部分。如果你需要“向上”的attribs恰好是120mb“向左”,它是一个PITA,你需要努力连接各个部分。但考虑到RSS,我可以从中间切下一块,找到第一个“<item>”和下一个“</ item>”并拥有我需要的东西,前提是我预先缓存了频道信息... - dandavis
@dandavis我添加了一个XML代码的示例。有成千上万的块从最终开始 <case-file> 这是一块可以被大块解析的东西吗? - Ken
为什么它必须是PHP?是因为它将成为更大的系统/平台的一部分,在PHP或其他东西? - Rcynic


答案:


所有步骤当然可以使用 node.js。有一些模块可以帮助您完成以下每项任务:

    • 节点的cron:允许您在节点程序中轻松设置cron任务。另一种选择是在您的操作系统上设置一个cron任务(为您喜欢的操作系统提供大量资源)。
    • 下载:模块可以轻松地从URL下载文件。
  1. XML的流:允许您流式传输文件并注册解析器遇到某些XML元素时触发的事件。我已成功使用此模块来解析KML文件(授予它们比文件小得多)。

  2. 节点的Postgres:PostgreSQL的节点客户端(我确信有许多其他常见RDBMS的客户端,PG是我到目前为止唯一使用过的客户端)。

这些模块中的大多数都有非常好的例子可以帮助您入门。以下是您可能设置XML流媒体部分的方法:

var XmlStream = require('xml-stream');
var xml = fs.createReadStream('path/to/file/on/disk'); // or stream directly from your online source
var xmlStream = new XmlStream(xml);
xmlStream.on('endElement case-file', function(element) {
    // create and execute SQL query/queries here for this element
});
xmlStream.on('end', function() {
    // done reading elements
    // do further processing / query database, etc.
});

7
2017-12-16 03:58



由于看起来您的数据没有任何关系(平面记录),您可以将每条记录保存在NoSQL数据库(例如mongo db)中。所有提到的查询都应该易于从用户输入编写/生成。数据以JSON格式存储和访问,使得在node.js中访问它非常容易。 - forrert


您确定需要将数据放在关系数据库中,还是只想搜索它?

似乎没有任何实际的 关系 在数据中,因此将它放在文档搜索索引中可能更简单 ElasticSearch

任何自动XML到JSON转换器都可能产生合适的输出。大文件大小是个问题。 这个图书馆尽管它的总结说“不流式”,但如果你检查源代码,实际上是流式传输,所以它对你有用。


6
2017-12-18 16:23



不,我不确定。这是我想弄清楚的事情之一。我想允许用户按代码,序列号,名称等搜索数据。上面的xml是实际XML文件中所有各种字段的简化版本。目标是允许快速搜索,并灵活地显示数据的最终显示方式。 - Ken
他们希望从数据库中检索哪种类型的数据?所有XML文件都是相同的格式吗?是否有其他关系或字段在当前示例XML文件中不明显?也许更多的数据示例和对计划使用数据的描述会有所帮助。 - Taraz
如果一个实体中没有包含对另一个实体的引用的字段(例如,通过ID),那么您可能不需要关系数据库。 - mwhite
@Taraz我已经在问题中添加了更多信息。希望,这有帮助。如果您需要更多说明,请与我们联系。 - Ken


你写的时我有xml文件的任务。这是我使用的原理:

  1. 我存储的所有传入文件都在DB(XMLTYPE)中,因为我需要一个源文件信息;
  2. 所有传入的文件都使用XSL转换进行解析。例如,我看到这里有三个实体:fileInfo,fileCases,fileClassification。您可以编写XSL转换来编译3种实体类型的源文件信息(在标签FileInfo,FileCases,FileClassification中);
  3. 当您有输出转换的XML时,您可以制作3个过程,将数据插入DB(DB区域中的每个实体)。

2
2017-12-22 08:17