Hallo,
bisher habe ich mich erfolgreich um die Anwendung von XML gedrückt. Leider geht das bei meinem aktuellen Projekt nicht mehr. Bei den zahlreichen möglichkeiten fällt es mir aber schwer mich zurecht zu finden.
Das Problem ist folgendes: Ich bekomme die Daten zu Produkten im XML-Format und habe bisher nicht ganz verstanden wie ich die in eine Postgress Datenbank bekommen könnte.
Eine möglichkeit ist ein Programm zu schreiben das die XML-Datei liest die Daten filtert und in die Datenbank einfügt. Aber geht das evtl. z.B. mit XSLT ohne selbst ein Programm schreiben zu müssen. Was mir sehr helfen würde ist ein Hinweis in welche Richtung ich weiter suchen sollte.
Viele Grüße
Alexander
Hallo Alexander,
wenn ich dich recht verstehe willst du nur Teile der Daten aus dem XML ablegen, und das in einer bestimmten Struktur. Das ganze XML einfach als Text in ein Feld zu schreiben macht ja wohl keinen Sinn.
Einfacher dürfte es in der Anwendung sein, das per Programm zu erledigen. Grundsätzlich kann .net (ich nehme c#) XML gut verarbeiten und DB´s ansprechen. (Postgress kenne ich nicht).
Alternativ kann man per XSLT ein csv erzeugen, das man dann einlesen könnte. Wenn das häufiger vorkommt ist das aber sehr lästig. Hast du „einmal im Jahr viele Daten“ oder „mehrmals täglich ein paar“?
Zum XSLT:
<?xml version="1.0" encoding="ISO-8859-1" ?>"
Spalte 1
" "
Spalte 2
" "
/xsl:template>
„“ „“" "
Das sollte dann ein XSV auf den Schirm bnringen. Das speichern und importieren. Man könnte natürlich das Bilden des csv in ein Programm stecken, aber dann kann man auch direkt in die DB schreiben, meine ich.
mfg
Dirk
XML-Dokument in Postgress speichern
Hallo Dirk.Pegasus,
danke für die schnelle Antwort.
wenn ich dich recht verstehe willst du nur Teile der Daten aus
dem XML ablegen, und das in einer bestimmten Struktur. Das
ganze XML einfach als Text in ein Feld zu schreiben macht ja
wohl keinen Sinn.
Ja genau, ich möchte nur die im XML enthaltenen Produktinformationen in der Datenbank haben. Die Datenbank wird von einem Online-Shop verwendet und das ganze läuft auf einem Linux-Server.
Einfacher dürfte es in der Anwendung sein, das per Programm zu
erledigen. Grundsätzlich kann .net (ich nehme c#) XML gut
verarbeiten und DB´s ansprechen. (Postgress kenne ich nicht).
Ich würde jetzt zwar C++ bevorzugen da alle meine Programme in C++ geschrieben sind. Mit Xerces-C++ (XML-Parser) oder Xalan-C++ (XSLT-Prozessor) des Apache-Teams sollte es doch gut möglich sein XML zu Verarbeiten. Welches von den beiden wäre für meinen zweck den die bessere Wahl? Nach meinem bisherigen Wissen würde ich Xerces nehmen.
PostgreSQL ist ein freies und sehr Leistungsfähiges Datenbanksystem es gibt davon glaube ich auch eine Windowsversion. Wenns Dich intressiert unter www.postgresql.org ist es zu finden.
Alternativ kann man per XSLT ein csv erzeugen, das man dann
einlesen könnte. Wenn das häufiger vorkommt ist das aber sehr
lästig. Hast du „einmal im Jahr viele Daten“ oder „mehrmals
täglich ein paar“?
Über ein CSV wäre auch eine möglichkeit. Ich würde mir gerne diesen Umweg ersparen. Daten bekomme ich in unregelmäßigen Abständen von den Herstellern. Meist treffen Daten aber mehrmals in der Woche ein. Die Mengen sind unterschiedlich können aber bis zu einigen hundert Megabyte betragen.
Grüße
Alexander
Hallo Alexander,
da ich deine (und die von C++, Postgress) Fähigkeiten nicht kenne zunächst eher grundsätzliches (Alles in c#, es sollte aber etwas gleichwertiges in c++ geben!?):
Über einen FileDialog das XML suchen
per
XmlDocument XmlDoc = new XmlDocument ();
xmlDoc.Load(Server.MapPath(@fileName));
laden
Dann per
foreach(XmlNode n in xmlDoc.SelectNodes("//elemente"))
{
Darin per
val1 = n.SelectSingelNode("//wert1")
Die Werte einsammeln und per SQL Befehl in die DB schreiben.
}
alle Inhalte in eine Schleife bringen.
Was du im SQL alles machen musst? Ggfs. kann ich dir für SQL helfen.
mfg
Dirk.Pegasus
XML-Dokument in Postgress speichern
Hallo Dirk.Pegasus,
foreach(XmlNode n in xmlDoc.SelectNodes("//elemente"))
Um mit der Schleife die Elemente zu Suchen muß ich aber deren Namen kennen oder gibt der immer das nächste vorhandene zurück?
Mal ein kleines Beispiel aus einer Datei von mir.
3827269709
So sieht ein kleiner Ausschnitt der Datei aus. Warum wird eigentlich der Tag-Name in den refname noch einmal angegeben?
Der Wert den ich in diesem Fall brauche ist der Name „IDValue“ und die Zahl „3827269709“. Verstehe ich das richtig in der Schleife von Dir bekomme ich dann der Reihe nach die Elemente. Das sind dann die in Spitzen Klammern angegebenen Namen also Produkt, ProductIdentifier und IDValue. Innerhalb der Schleife würde ich dann z.B. den Wert „3827269709“ für „IDValue“ erhalten.
Ich hoffe ich habe das richtig verstanden oder liege ich da falsch?
Grüße
Alexander
Hallo Alexander,
foreach(XmlNode n in xmlDoc.SelectNodes("//elemente"))
Das erzeugt quasi eine Liste von allen Knoten, die den TagNamen „elemente“ (bei dir „//Produkt“) haben. Der XmlNode repräsentiert also nach und nach allen Knoten des Typs, samt aller etwaiger Kinder. Das „//“ besagt, dass alle gefunden werden, egal auf welcher Ebene die Knoten liegen. IdR verwendet man zwar „./Produkt“, wenn man auf dem Eltern des Produktes steht. Aber wenn man nicht sicher ist auf welcher Ebene man die Knoten findet und diese nihct „in sich“ geschachtelt sind macht das keinen Unterschied.
In deinem Beispiel kannst du dann mit
wert1 = n.SelectSingleNode("./ProductIdentifier/IDValue").Innertext
einen Wert holen.
Bei den Methoden:
n.SelectSingleNode(ausdruck)
n.SelectNodes(ausdruck)
ist Ausdruck ein XPath (quasi ein Filter) Statement das innerhalb des Knotens n alle validen Knoten ermittelt. Bei SelectSingleNode im Zweifel den ersten (falls es mehrere gibt) bei SelectNodes eine Liste aller validen Knoten.
Zu XPath solltest du mal bei SelfHtml reinschauen. Ist etwas mühsam aber recht mächtig.
Ich hoffe ich habe das richtig verstanden oder liege ich da
falsch?
Richtig verstanden, du liegst nicht falsch.
mfg
Dirk.Pegasus
XML-Dokument in Postgress speichern
Hallo Dirk.Pegasus,
ich hatte zwar schon einiges gelesen nur mit dem verstehen klappte es noch nicht so ganz. Mit Deiner Erklärung sehe ich schon mal etwas Licht in diesem Wald. Danke!
Dann ist es aber erforderlich das mein Programm alle Elemente Namentlich kennt. Da ich die Daten von verschiedenen Herstellern erhalte könnte es jetzt natülich sein das Elemente enthalten sind die ich noch nicht berücksichtige. Gibt es eine möglichkeit irgendwie herauszubekommen welche Elemente man nocht nicht verarbeitet hat. Auch wenn man deren Namen nicht kennt. Damit könnte man sich davor schützen beim Import Daten zu verlieren ohne das man es mitbekommt.
Grüße und ein schönes Wochenende
Alexander
Hallo Alexander,
das hab ich noch nicht probiert.
Aber eine Idee (nicht ganz ausgereift):
Eine Mappingtable in die DB die Anbieter, TagName und DB_FeldName (und ne id) enthält. Alle werde ja wohl in „einer“ Tabelle landen, ansonsten noch die Tabelle mit aufnehmen.
ArrayList TagNameList = new ArrayList();
//in das alle Zeilen des Anbieters laden …
foreach(XmlNode element in doc.SelectNodes("//Artikel"))
checkNode(element);
Der Test der Kinder muss rekursiv aufgerufen werden, daher in eine eigene Methode
private void checkNode(XmlNode n)
{
foreach (XmlNode childs in n)
{
if (n.HasChildNodes)
foreach (Xmlnode Childs in n.ChildNodes)
checkNode(n);
else
{
//Contains selber schreiben ???
if (Contains(tagNameList, n.Name))
speicherInDb(anbieterTags[„DB_FeldName“], n.selectSingleNode("//" + tagName));
else
Response.Writeln("nicht verarbeitet: " + n.TagName );
}
}
}
Das mal als Idee. Da ich deine DB und die Daten nicht kenne muss man das anpassen.
mfg
Dirk.Pegasus
XML-Dokument in Postgress speichern
Hallo Dirk.Pegasus,
Deine Idee ist gut ich werde das mal ausprobieren.
Was DOM ist, ist mir schon bekannt aber was SAX ist habe ich bis jetzt noch nicht verstanden. Oder wie DOM und SAX zusammenhängen?
Vielleicht kannst Du mir das ja kurz erklären 
Viele Grüße
Alexander
Hallo Alexander,
Was DOM ist, ist mir schon bekannt aber was SAX ist habe ich
bis jetzt noch nicht verstanden. Oder wie DOM und SAX
zusammenhängen?
Leider kann ich das nicht, einfach machen …
mfg
Dirk.Pegasus
XML-Dokument in Postgress speichern
Hallo Dirk.Pegasus,
Was DOM ist, ist mir schon bekannt aber was SAX ist habe ich
bis jetzt noch nicht verstanden. Oder wie DOM und SAX
zusammenhängen?
Leider kann ich das nicht, einfach machen …
Ich habe jetzt noch ein bischen in meinen Fachbüchern gelesen und wenn ich es richtig Verstanden habe ist SAX gegenüber DOM nur eine andere Art um mit einem XML-Dokument zu arbeiten.
Bei der Verarbeitung nach DOM wird der gesamte Objekt-Tree im Speicher gehalten so kann das Dokument leicht manipuliert und nicht sequenziell verarbeitet werden. Diese Art der Verarbeitung ist aber relativ langsam.
Wenn man ein XML-Dokument nach SAX verarbeitet wird es einmal sequenziell durchlaufen und dabei die Daten gefiltert die man braucht. Bei SAX wird auch kein DOM-Tree im Speicher erstellt.
Für mein Problem könnte dem zu Folge die SAX Methode ausreichend sein. Ich will das XML-Dokument ja nur einmal lesen und die Nutzdaten in einer Datenbank ablegen. Auserdem muß ich bei meinem kleinen Linux-Cluster etwas auf die benötigte Rechenleistung schauen und SAX sollte da geringere Anforderungen stellen.
Viele Grüße
Alexander
XML-Dokument in Postgress speichern
Hallo,
für alle die es vielleicht intressiert und auch Probleme mit den Fachbüchern haben die Lobeshümnen zwar auf XML singen aber wenig hilfreiches zu bieten haben. Hier ein Link auf ein Tutorial was mir sehr geholfen hat.
http://www.uzi-web.de/index.html
Viele Grüße
Alexander