【问题标题】:Import XML file into PostgreSQL Database将 XML 文件导入 PostgreSQL 数据库
【发布时间】:2015-08-19 10:19:50
【问题描述】:

几天前I managed it to export 3 different PgSQL tables into one XML file。现在,我想导入相同的文件。我搜索了大约 2 个小时,但只找到了将 XML 导入一个表的解决方案。这是 XML 的结构

 <?xml version="1.0" encoding="UTF-8"?>

 <Table1 Col1="xxx" Col2="xxx">
    <Table2 Col1="xxx">
       <Table3 Col1="xxx" Col2="xxx" Coln="xxx"/>
    </Table2>
    <Table2 Col1="xxx"/>
    <Table2 Col1="xxx">
       <Table3 Col1="xxx" Col2="xxx" Coln="xxx"/>
    </Table2>
 </Table1>

表 1 包含表 3,表 2 包含表 3。

表是 XMLWriterElements,列是 XMLWriterAttributes。

更新:我解决了问题并想向您展示我的结果,如果有人遇到相同或相似的问题:

$reader = new XMLReader();

if ($reader->open("tk.xml")) {
    while($reader->read()) {
        if ($reader->nodeType == XMLReader::ELEMENT &&reader->name == 'Table 1') {
            $knr = $reader->getAttribute('Col1');
            $kname = $reader->getAttribute('Col2');

            $SQL = "";
            $SQL .= "SELECT
                        (table1).col1 AS col1, (table1).col2 AS col1
                    FROM
                        table1
                        ";
            $SQL .= "INSERT INTO table1 (";
            $SQL .= "col1, col1";
            $SQL .= ") VALUES (";
            $SQL .= "'".$col1."', '".$col1."'";
            $SQL .= ");".PHP_EOL;
            echo $SQL;


    }
               if ($reader->nodeType == XMLReader::ELEMENT 
                    &&reader->name == 'Table 2') { ......}

                       if ($reader->nodeType == XMLReader::ELEMENT
                            &&reader->name == 'Table 3') { ......}
  }
    $reader->close();
}   

我希望,这些代码对某人有所帮助。

【问题讨论】:

  • 数据库实际上是一个包含行和列的平面表。表将大型数据库分解为视图,这些视图是单个平面表的子集。您的 XML 有嵌套表,很难输入数据库。我将创建一个包含 Col1、Col2 和 Coln 的表,然后将数据输入到单个表中,而不是将数据输入到三个单独的表(表 1、表 2 和表 3)中。
  • 您在更新中粘贴了代码,但没有说明您遇到了什么问题、遇到的错误等。快速浏览一下,我可以看到许多问题:您似乎使用 MySQL 样式的标识符引用 , not ANSI SQL style quoting with "`。您还违反了我的明确建议,在您的 SQL 中连接值,如果您执行该 SQL,则让您为 SQL 注入敞开大门
  • 如果您仍然被粘贴在编辑中的代码所遇到的任何问题所困扰,请发布一个新问题,并附上指向该问题的链接以获取上下文,即您的代码小节遇到问题、问题描述、您收到的确切错误消息等。您可能会发现在编写问题的过程中自己解决了问题。 (我不能很好地遵循您的代码,似乎有很多重复;您是否将其中的一部分粘贴了两次?)
  • 好的,抱歉,我不明白那部分,因为我对 PHP 比较陌生。我忘了保存我写问题的编辑。我修改它并稍后发布我的结果
  • 好的,我重新考虑并在 OP 中编写了工作代码,也许我可以做得更好?抱歉我的问题,但我在 3 周前开始使用 PHP

标签: php sql xml postgresql xmlwriter


【解决方案1】:

绝对不可能用 XMLWriter 导入它,因为那是用于 XML 输出的。你想要XMLReader,它是一个类似游标的 XML 拉解析器。

您需要反转the logic you used for the output。遍历 XML 文档。当您看到一个新节点时,将其插入数据库,然后向下插入并记录其 ID,以便在插入内层的外键引用时使用它。

您的逻辑将类似于以下伪代码解释:

xmldocument = [create a new XMLReader from the XML text]

cur_table1_id = null;
cur_table2_id = null;

element = xmldocument.get_next_element();
do {
   if (element.name == 'Table1')
   {
     insert_table1(element);
     cur_table1_id = element.getAttribute('id');
   }
   else if (element.name == 'Table2')
   {
     insert_table2(element, cur_table1_id);
     cur_table2_id = element.getAttribute('id');
   }
   else if (element.name == 'Table3')
   {
     insert_table3(element, cur_table2_id);
   }

   element = get_next_element();
} while (element != null);

您可以阅读XMLReader API documentation 和适当的示例,并将粗略的逻辑大纲转化为手头任务的实现。同样,您需要阅读 PostgreSQL 客户端界面上的 PHP 文档来了解如何进行插入。

关于后者的免费提示:不要使用pg_query 和字符串连接/插值。使用 PDO 或 pg_query_params。原因见the PHP manual on SQL injection


对于想知道我为什么忽略关闭标签的读者:在这种情况下,除非 XML 格式错误,否则它们无关紧要&lt;table2&gt; 等。无论如何,这些情况通过 XML 模式验证比在程序中在代码中处理更好。

【讨论】:

  • 哦,是的,我的意思是 XMLReader。我的错。我会试试这个。提前感谢您的快速和专业的回答。编辑:可悲的是,我已经每天获得 30 票。明天将对此进行投票
猜你喜欢
  • 1970-01-01
  • 2019-10-05
  • 2013-10-01
  • 1970-01-01
  • 2021-10-20
  • 1970-01-01
  • 1970-01-01
  • 2012-06-03
  • 2018-05-02
相关资源
最近更新 更多