Импорт XML в базу данных PostgreSQL или Преобразование XML -> CSV -> PostgreSQL - PullRequest
0 голосов
/ 08 апреля 2011

У меня есть XML-файл

<Cluster clsId="UNIPR_NIRI_PARDP" semType="geneProt"> <Entry entryId="UNIPR_NIRI_PARDP_1" baseForm="Protein nirI" type="PREFERRED">

<Variant WRITTENFORM="FMN-binding domain protein" type="orthographic"/> <Variant WRITTENFORM="FMN-binding domain-containing protein" type="orthographic"/> <Variant WRITTENFORM="unknown" type="orthographic"/> <Variant WRITTENFORM="FMN-binding" type="orthographic"/> <Variant WRITTENFORM="Pden_2486" type="orthographic"/> <Variant WRITTENFORM="nirI" type="orthographic"/> <SourceDC sourceName="BioThesaurus" sourceId="Q51699"/> <PosDC posName="POS" pos="N"/> <DC att="uniprot_ac" val="Q51699"/> <DC att="speciesNameNCBI" val="318586"/>

</Entry> </Cluster>

Мне нужно импортировать этот контент в postgresql.Пожалуйста, помогите мне в этом отношении либо прямая процедура или конвертировать XML в CSV в PostgreSQL.

Мне нужны таблицы со столбцами, такие как

clsid, entryid, semType, baseForm, вариант (записанная форма), вариант(тип), постоянный ток (att), постоянный ток (val)

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 02 мая 2011

Я сделал это с помощью Ruby с помощью пакетов noko-giri и open-uri.Мой входной файл очень большойМногие из синтаксических анализаторов потерпели неудачу, и noko-giri помог в этом.

Я предоставил ответ в трех столбцах: baseForm-варианту (письменной форме) -dc (вал).Эта информация может быть четкой информацией для вопроса.

require 'nokogiri'
require 'open-uri'

doc = Nokogiri::XML(File.open("xai"))
ent = doc.xpath("//Entry")

value = String.new
ent.each do |e| 
    d = e.xpath("DC")   
    d.each do |f|       
        if f.attributes["att"].to_s =~ /uniprot_ac/
            value = f.attributes["val"].to_s
        end
    end
    f = e.xpath("Variant")  
    f.each do |g|
        puts "#{e.attributes["baseForm"].to_s}\t" + "#{g.attributes["WRITTENFORM"].to_s}\t" + "#{value}"
    end 
end
0 голосов
/ 08 апреля 2011

Сначала проанализируйте ваш xml-файл, чтобы получить файл (ы), которые содержат всю необходимую информацию.

Например, если вы хотите иметь только одну таблицу с атрибутами clsid, entryid, semType, baseForm, вариант (записанная форма), вариант (тип), dc (att), dc (val), тогда вам просто нужен один файл, который имеет эти атрибуты (разделенные некоторым символом).Каждая строка в файле будет соответствовать каждой строке в таблице.

Далее вы создадите схему таблицы в Postgresql.Затем используйте команду COPY Postgresql, которая копирует все данные из файла в таблицу.

Обратите внимание, что если ваш xml-файл огромен, вы должны использовать анализатор событий.Что-то вроде SAX, например, StAX в Java.

EDIT * ПРИМЕЧАНИЕ *: использованные библиотеки: stax2-api-3.1.1.jar, woodstox-core-asl-4.1.1jar Вот код (надеюсь, он делает то, что вам нужно, если нет, я уверен, что он поможет вам начать работу):

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package test;

import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.net.MalformedURLException;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import java.util.ArrayList;
import org.codehaus.stax2.XMLInputFactory2;
import org.codehaus.stax2.XMLStreamReader2;

public class Main {

    /**
     * @param args the command line arguments
     */

    /*
     * dc(att), dc(val)
     */
    @SuppressWarnings("CallToThreadDumpStack")
    public static void main(String[] args) throws MalformedURLException, IOException, XMLStreamException {
        FileInputStream fstream = new FileInputStream(args[0]);
        Reader in = new InputStreamReader(fstream, "UTF-8");
        XMLInputFactory2 factory = (XMLInputFactory2) XMLInputFactory.newInstance();
        XMLStreamReader2 parser = (XMLStreamReader2) factory.createXMLStreamReader(in);

        FileOutputStream outStream = new FileOutputStream("/home/aseke/Desktop/out.txt");
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(outStream, "UTF-8"));


        boolean isCluster = false;
        ArrayList<String> dc = new ArrayList<String>();
        ArrayList<String> variants = new ArrayList<String>();

        /* You actually do not need all of these variables, it's just for clarity */
        String clsID = null;
        String semType = null;
        String varWritten = null;
        String varType = null;
        String entryID = null;
        String baseForm = null;
        String dcAtt = null;
        String dcVal = null;
        String s = null;
        while (true) {
            int event = parser.next();
            if (event == XMLStreamConstants.END_DOCUMENT) {
                parser.close();
                break;
            }

            if (event == XMLStreamConstants.START_ELEMENT) {
                String tag = parser.getLocalName();

                if (tag.equals("Cluster")) {
                    isCluster = true;
                    clsID = parser.getAttributeValue(0);
                    semType = parser.getAttributeValue(1);
                } else if (tag.equals("Entry") && isCluster) {
                    entryID = parser.getAttributeValue(0);
                    baseForm = parser.getAttributeValue(1);
                } else if (tag.equals("Variant") && isCluster) {

                    varWritten = parser.getAttributeValue(0);
                    varType = parser.getAttributeValue(1);

                    variants.add(varWritten + "~" + varType);
                } else if (tag.equals("DC") && isCluster) {
                    dcAtt = parser.getAttributeValue(0);
                    dcVal = parser.getAttributeValue(1);

                    dc.add(dcAtt + "~" + dcVal);
                }
            }

            if (event == XMLStreamConstants.END_ELEMENT && isCluster) {
                if (parser.getLocalName().equals("Cluster")) {
                    isCluster = false;
                    //clsid, entryid, semType, baseForm, variant(writtenform), variant(type), dc(att), dc(val)
                    // Use tabs as delimiter for Postgre COPY
                    String outStr = clsID + "/t" + entryID + "/t" + semType + "/t" + baseForm + "/t";

                    /* Add all variants */
                    for (String var : variants) {
                        String tmp[] = var.split("~");
                        varWritten = tmp[0];
                        varType = tmp[1];
                        outStr += varWritten + "/t" + varType + "/t";
                    }
                    /* Add al DCs */
                    for (String ss : dc) {
                        String[] tmp = ss.split("~");
                        dcAtt = tmp[0];
                        dcVal = tmp[1];
                        outStr += dcAtt + "/t" + dcVal + "/t";
                    }
                    // remove last tab "\t"
                    outStr = outStr.substring(0, outStr.length() - 2);
                    out.write(outStr);
                    variants.clear();
                    dc.clear();

                }
            }
        }

        // close all streams
        fstream.close();
        out.close();
        outStream.close();
    }
}

Я отформатировал ваш ввод xml .Таким образом, входной файл выглядит так:

<Cluster clsId="UNIPR_NIRI_PARDP" semType="geneProt">
    <Entry entryId="UNIPR_NIRI_PARDP_1" baseForm="Protein nirI" type="PREFERRED">
        <Variant WRITTENFORM="FMN-binding domain protein" type="orthographic"/>
        <Variant WRITTENFORM="FMN-binding domain-containing protein" type="orthographic"/>
        <Variant WRITTENFORM="unknown" type="orthographic"/>
        <Variant WRITTENFORM="FMN-binding" type="orthographic"/>
        <Variant WRITTENFORM="Pden_2486" type="orthographic"/>
        <Variant WRITTENFORM="nirI" type="orthographic"/>
        <SourceDC sourceName="BioThesaurus" sourceId="Q51699"/>
        <PosDC posName="POS" pos="N"/>
        <DC att="uniprot_ac" val="Q51699"/>
        <DC att="speciesNameNCBI" val="318586"/>
    </Entry>
</Cluster>

Вывод выглядит следующим образом .Обратите внимание, что он ограничен вкладками.Позднее вкладки будут использоваться в качестве разделителя в команде Postgre COPY.Вы можете изменить разделитель на любой другой.

UNIPR_NIRI_PARDP/tUNIPR_NIRI_PARDP_1/tgeneProt/tProtein nirI/tFMN-binding domain protein/torthographic/tFMN-binding domain-containing protein/torthographic/tunknown/torthographic/tFMN-binding/torthographic/tPden_2486/torthographic/tnirI/torthographic/tuniprot_ac/tQ51699/tspeciesNameNCBI/t318586
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...