【问题标题】:Converting large XML file to relational database将大型 XML 文件转换为关系数据库
【发布时间】:2015-11-13 23:00:37
【问题描述】:

我正在尝试找出完成以下任务的最佳方法:

  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 文件中)组织这些搜索结果。例如,用户可能希望查看在 &lt;text&gt; 元素中包含特定单词的所有案例文件。或者,用户可能希望查看包含主代码 025(&lt;primary-code&gt; 元素)并在特定日期(&lt;filing-date&gt; 元素)之后提交的所有案例文件。

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

【问题讨论】:

  • 取决于文件,我认为它不能(容易)在节点或许多 php 设置中完成;如果您真的需要解析 XML,那将是一大堆内存……如果您可以逐块“抓取”xml 块(如果它是平面 + 线性的,如 RSS 文件),那么任何事情都可以工作。你打破一个块,解析小块,然后用新插入的行更新数据库。
  • @dandavis 谢谢。 “平面+线性”是指不超过一深吗?
  • 基本上。它的离散部分开始和结束的地方很重要。如果标签和可预测性周围有空格,那么您可以可靠地解析它的片段。如果您需要来自“顶部”的属性恰好是“左侧”120mb,那么它是一个 PITA,您需要努力连接各个部分。但考虑 RSS,我可以从中间切下一块,寻找第一个“”和下一个“”并拥有我需要的东西,前提是我预先缓存了频道信息......跨度>
  • @dandavis 我添加了 XML 代码的样例。有数千个以&lt;case-file&gt;结尾的块,这是可以逐块解析的吗?
  • 为什么一定要php?是因为它将成为 php 中更大的系统/平台的一部分,还是其他什么?

标签: javascript python xml node.js relational-database


【解决方案1】:

所有步骤都可以使用node.js 完成。有一些模块可以帮助您完成这些任务:

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

  2. node-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.
});

【讨论】:

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

您确定需要将数据放入关系数据库中,还是只想进行一般性搜索?

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

任何自动 XML 到 JSON 转换器都可能产生合适的输出。大文件大小是一个问题。 This library,尽管它的摘要说“不是流式传输”,但如果您检查源代码,它实际上是流式传输,因此它对您有用。

【讨论】:

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

正如您所写,我有处理 xml 文件的任务。这是我使用的主体:

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

【讨论】:

    猜你喜欢
    • 2019-09-13
    • 2017-08-14
    • 2010-10-26
    • 1970-01-01
    • 2015-11-15
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    • 2013-12-25
    相关资源
    最近更新 更多