简体   繁体   中英

Import XML file into PostgreSQL Database

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM