Import XML file into PostgreSQL Database

醉酒当歌 提交于 2019-12-08 05:38:30

问题


A few days ago I managed it to export 3 different PgSQL tables into one XML file. Now, I'd like to import the Same file. I've searched for about 2 hours but only found solutions for Importing a XML into one Table. Here ist the structure of the 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>

Table 1 contains Table 3 and table 2 contains Table 3.

The tables are XMLWriterElements, the columns XMLWriterAttributes.

UPDATE: I solved the problem and want to show you my results, if someone ha the same or similar problem:

$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();
}   

I hope, thos code will help someone.


回答1:


It is absolutely not possible to import this with XMLWriter, because that's for XML output. You want XMLReader, which is a cursor-like pull parser for XML.

You need to reverse the logic you used for the output. Iterate over the XML document. When you see a new node, insert it into the database, then descend into it and keep a record of its ID so you can use it when inserting foreign-key references for the inner layers.

Your logic will look something like the following pseudocode explanation:

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);

It's up to you to read the XMLReader API documentation and appropriate examples and turn that rough logic outline into an implementation of the task at hand. Similarly, you'll need to read the PHP documentation on the PostgreSQL client interface to figure out how to do the inserts.

Free tip on the latter: do not use pg_query and string concatenation/interpolation. Use PDO, or pg_query_params. For why, see the PHP manual on SQL injection.


For readers wondering why I ignored close tags: In this case they don't matter unless the XML is malformed, with a <table3> directly inside <table1> with no <table2>, or with a <table1> inside a <table2>, etc. Those cases are better handled by XML schema validation than they are procedurally in the code, anyway.



来源:https://stackoverflow.com/questions/32092750/import-xml-file-into-postgresql-database

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!