Verfahrensweise Daten aus dem Internet abfragen

MiMa

Top Contributor
Hallo,

ich habe im Unterforum Java Anfänger gepostet, wie man Informationen aus dem Internet abfragt.
Leider habe ich noch keine Lösung finden können. Ich arbeite gerade im Buch JAXB 2.0 vom Hanser Verlag und von Galileo Computing Einstieg in XML.

Leider ist es viel und umfangreich und zur Erstellung eines Abfragemoduls würde ich gerne wissen wie man da am besten vorgeht.

So wie ich das erkennen konnte habe ich in meinem Java Programm der Klasse Buch, die Instanzvariablen enthalten und die durch die Datenbank über die "Deutsche Nationalbibliothek" gefüllt werden sollen.

Ich habe die Instanzvariable ISBN, einen Inhalt, den ich an die Datenbank sende.

Wie ich das verstanden haben, muss ich diese Information an die Datenbank senden.
DNB - SRU-Schnittstelle
Diese muss formuliert werden, so das der Inhalt der Instnazvariable in die URL an die Datenbank eingeflochten wird.
Ich denke mal das es ungefähr so aussehen muss?
Code:
http://services.dnb.de/sru/dnb/?version=1.1/&operation=searchRetrieve/&query=ISBN&recordSchema=MARC21-xml

Dann erhalte ich eine Antwort die mir ein XML zurückgibt.
Wie das genau funktioniert, weiss ich noch nicht! Ist die XML dann im Hautspeicher, auf Festplatte???

Also diese XML gilt es dann zu konvertieren und zwar so das es dann zu Java Passt und die Werte in die Instanzvariablen übergeben werden können. Ich glaube das heisst dann Unmarshall.

Das ganze wird dann realisiert, indem man XML-Schema definiert, in dem die XML als SchemaInstanz zurückgibt?

Ich habe schon einiges gelesen, aber der Zusammenhang ist noch nicht so ganz klar?

Was mache ich also als erstes?

1. Die Klasse Buch mit den Instanzvariablen anschauen und dazu ein XML Schema bauen?

Vielen Dank

Mi
 
J

JohannisderKaeufer

Gast
Code:
http://services.dnb.de/sru/dnb/?version=1.1/&operation=searchRetrieve/&query=ISBN&recordSchema=MARC21-xml

Ist so nicht ganz korrekt
Code:
http://services.dnb.de/sru/dnb/?version=1.1&operation=searchRetrieve&query=ISBN&recordSchema=MARC21-xml

Wenn man das als Link im Browser eingibt bekommt man:
[XML]<diagnostics>
<diag:diagnostic>
<diag:uri>info:srw/diagnostic/1/68</diag:uri>
<diag:details>Not authorized to send record in this schema</diag:details>
<diag:message>Not authorized to send record in this schema / MARC21-xml. No Account for IpAddress: DEINE IP ADRESSE</diag:message>
</diag:diagnostic>
</diagnostics>[/XML]

Das heißt das du dich dort registrieren mußt. Dann wird entweder eine ip Adresse, wenn du eine Feste besitzt mit deinem Konto verknüpft oder du bekommst ein Token mit dem du dich authentifizieren kannst. Du mußt dich allerdings erst registrieren.

Dann sieht ein Aufruf so aus: xXxX steht für das Token
Code:
http://services.dnb.de/sru/dnb/?version=1.1&operation=searchRetrieve&query=ISBN&recordSchema=MARC21-xml&accessToken=XxXxXxXxXxXxXxXxXxXx

Kurz gefaßt, wenn du was im Browser eingeben kannst und es kommt was halbwegs lesbares raus, dann stimmt schon mal der Aufruf.

Wie das genau funktioniert, weiss ich noch nicht! Ist die XML dann im Hautspeicher, auf Festplatte???

Normalerweise wird mittels java.net.URL("Die URL die aufgerufen werden soll"); ein URL Objekt erstellt.
Vergleichbar mit einem Link auf dem Desktop. Das URL Objekt bietet dann eine Methode openStream an die einen InputStream zurückliefert. Dieser kann dann ausgelesen werden. Aber man kann davon ausgehen, daß der Stream Inhalt dann irgendwo im Speicher landet.

Dieser InputStream läßt sich so ziemlich gleich behandeln wie ein FileInputStream, oder System.in, falls du diese schonmal verwendet hast.


In Java und überhaupt gibt es viele Möglichkeiten XML zu verarbeiten.

Un/Marshalling beschreibt den Prozess XML in Java-Objekte und Umgekehrt zu konvertieren.
Das XML Schema entspricht dann den Java Klassen.
Das XML Dokument entspricht dann einer Menge von Java Objekt Instanzen.

Je nachdem in welche Richtung man gehen möchte, so unterscheidet sich auch deren Vorgehensweise
 

MiMa

Top Contributor
Vielen Dank,

den Input-Stream habe ich noch nicht benutzt, werde mich aber damit auseinander setzen.

Wenn die URL ein Objekt erzeugt, und der Stream als XML Format zurückgegeben wird, dann wäre die weitere Verfahrensweise, den erhaltenen Inhalt zu konvertieren (Unmarshall) und in die Objektinstanzen der Klasse Buch zu überführen. :rtfm:

Mi
 

MiMa

Top Contributor
Ich habe ein Token und auch schon erfolgreich eine Suchanfrage über den Browser gemacht und eine gültige Rückanwort erhalten, die auch alle Informationen beinhaltet.

Als nächstes gilt wohl das Unmarshall zu machen.

Ich lese ausser in dem JAX buch noch XML-XSL für professionelle Einsteiger.

Das erlernen von XML ist ja genau wie bei Java ziemlich umfangreich und auch eine eigene Beschreibungssprache mit eigenen Datentypen und so.

Ich denke das wird noch ein ganze weile dauern.
Jetzt lerne ich erst mal das erstellen eines Schemas.

Ein XML Datenmodell werd eich wahrscheinlich nicht benötigen.

Mi
 

ARadauer

Top Contributor
Dann erhalte ich eine Antwort die mir ein XML zurückgibt.
Wie das genau funktioniert, weiss ich noch nicht! Ist die XML dann im Hautspeicher, auf Festplatte???

Du denkst zu kompliziert... Du meinst wahrscheinlich für XML muss man ein bauch lesen... das ist dazu da daten für maschine und menschen lesbar zu machen... da reicht ein 5 min tutorial...

hauptspeicher, festplatte... ja das kommt darauf an, wie du das ließst...

unmarshalling.... du kannst dir das ganze auch mit einfachen String operationen auslesen... oder bisschen komplexer dom oder ganz profi mäßig mit jaxb...

schick mir nochmal dein amazon dings projekt ich hab das nicht bekommen, ich hab morgen einwenig zeit, freundin ist auf einer hochzeit, da kann ich mir das ansehen...
 

MiMa

Top Contributor
Da ich der Meinung bin ein Buch lesen zu müssen, liegt daran das ich weder HTML gut kann noch weiss wie XML funktioniert.

Deshalb dachte ich mir mich mal mit den Grundlegenden Dingen vertraut zu machen.
Nach all der Recherche im Internet bin ich auf JAX gestossen.

Ich gebe zu es ist ziemlich umfangreich, aber ich dachte das wird so gemacht.
Da ich auch gerade in Java eingestiegen bin, war ich auch nicht sonderlich begeistert noch nebenbei XML zu machen. Ich denke aber das die Abfrage von Informationen aus dem Internet für mich bestimmt noch öfters von Bedeutung sein kann und deshalb möchte ich auch die Deutsche National Bibliothek abrufen können.

Mi
 

MiMa

Top Contributor
Ich wollte jetzt mal das Beispiel ausprobieren um zu verstehen, wie JDOM funktioniert.

Javabeginners - XML-Dateilesen

Allerdings muss neben dem Code auch noch die Klassen von JDOM geladen und installiert werden.
Der link ist auf der Seite ganz unten enthalten.

Ich habe dann mal JDOM 2.03 JDOM geladen und im Code sind dann immer noch import Probleme.

Code:
import org.jdom.Document; 
import org.jdom.Element; 
import org.jdom.JDOMException; 
import org.jdom.input.SAXBuilder; 
import org.jdom.output.XMLOutputter;

can not resolved

Habe dann auch noch die DJOM 1.13 ausprobiert, aber dort sind immer noch die gleichen Fehlermeldungen der importanweisungen?

In der API document habe ich die Klassen aber schon gefunden also müssen die doch irgendwo sein ??


Danke

Mi
 
Zuletzt bearbeitet:

MiMa

Top Contributor
So habe es gefunden.

Code:
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException; 
import org.jdom2.input.SAXBuilder;
import org.jdom2.input.sax.SAXBuilderEngine;
import org.jdom2.output.XMLOutputter;
import org.jdom2.output.support.*;

So geht es in JDOM 2.03.

Mi
 

MiMa

Top Contributor
Hi Mittlerweile habe ich es mit dem Tutorial geschafft aus einem XML Dokument ein paar Elemente auf die Konsole aus zu geben.
Ich habe da mal eine Frage bezüglich der Kindelemente die eine Reihe tiefer sitzen.

So sieht meine MXL aus:

[XML]
<?xml version="1.0" encoding="UTF-8"?>
<buch>
<titel>Algorithmen kompakt und verständlich</titel>
<untertitel>Lösungsstrategien am Computer</untertitel>
<inhalt>http://d-nb.info/989219313/04</inhalt>
<sachschlagwort>Algorithmus</sachschlagwort>
<buchreihe>Studium</buchreihe>
<verfasser>
<vorname>Markus>/</vorname>
<nachname>von Rimscha</nachname>
</verfasser>
<verlagname>Vieweg + Teubner</verlagname>
<isbn>9783834805690</isbn>
<i-s-b-n>978-3-8348-0569-0</i-s-b-n>
<erscheinungsjahr>2008</erscheinungsjahr>
<erscheinugsort>Wiesbaden</erscheinugsort>
<auflage>1. Aufl.</auflage>
<seiten>VIII, 144 S.</seiten>
<masse>24 cm</masse>
<bezugsbedinnungen>kart. : EUR 19.90</bezugsbedinnungen>
</buch>
[/XML]

Java Programm:

Java:
import java.io.File;
import java.io.IOException;
import java.util.List;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.XMLOutputter;

public class JDOMBuchLesen
{
    public static void main(String[] args)
    {
        // initialisieren JDOM Objekt
        Document buchObjekt = null;
    
        // File Objekt Erzeugen
        File buchFile = new File("buch.xml");
    
        try
        {
            // Das SAX Buch-Dokument erstellen
            SAXBuilder jdomBuchDokument = new SAXBuilder();
            
            // JDOM Objekt den Inhalt der XML einlesen
            buchObjekt = jdomBuchDokument.build(buchFile);
            
            // XML Inhalt in die Variable schreiben (Writer)
            // XMLOutputter xmlAusgabe = new XMLOutputter();
            
            // komplettes XML Dokument ausgeben
            // xmlAusgabe.output(buchObjekt, System.out);
            
            // Wurzelelement erzeugen
            Element element = buchObjekt.getRootElement();
            System.out.println("\nWurzelelement: " + element);
            
            // Name aus dem Wurzelelement ausgeben
            System.out.println("Wurzelelementname: " + element.getName());
            
            // Liste aller direkten Kindelemente eines elementes erstellen        
            List alleKinder = (List) element.getChildren();
            
            // Alle Kindelemente nacheinander ausgeben            
            for (int i=0; i<15; i++)
            {
            System.out.println(i + ". Kindelement: " + ((Element) alleKinder.get(i)).getName());
            }
                        
            // Eine Liste aller direkten Kindelemente eines benannten Elementes Erstellen
            List benannteKinder = element.getChildren("verfasser");
            // Das erste Kindelement ausgeben
            System.out.println("benanntes Kindelement: " + ((Element) benannteKinder.get(0)).getName());
        }
        catch (JDOMException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

Es soll dann eine Liste der Kindelemente von den benannten Element Verfasser ausgeben.
Wenn ich den Wert 0 lasse, gibt es verfasser aus, gerechnet hatte ich mit name(0) und vorname(1)

Danke

Mi
 

Templarthelast

Bekanntes Mitglied
Vielleicht brauchst du doch ein xml Buch :p

Du brauchst die Kinderelemente von dem Knoten "Verfasser" momentan gibst du nur den Namen des 0. Element der Liste von Knoten im Rootelement mit Namen "Verfasser" aus.
 

MiMa

Top Contributor
Vielen Dank,
das habe ich auch gesehen, als ich den code ausgeführt habe.

Im Tutorial wird das auch nicht gezeigt, wie mann dann die weiteren Kindelemente heran kommt. ???:L

Auch die Syntax ist mir neu: ((Element) alleKinder.get(0)).getName())
Ist wohl abhängig der Klassenbiblothek ob der Typ in Klammern geschrieben wird oder nicht.

Mit der Zeile

[XML]
System.out.println("Verfasser Kinder: " + ((Element) benannteKinder.get(0)).getChildren());
[/XML]

erhalte ich die Ausgabe

Code:
Verfasser Kinder: [[Element: <vorname/>], [Element: <nachname/>]]

[XML]
System.out.println("Verfasser Kinder: " + ((Element) benannteKinder.get(0)).getChildren().get(0));
System.out.println("Verfasser Kinder: " + ((Element) benannteKinder.get(0)).getChildren().get(1));
[/XML]

Ausgabe:

Code:
Verfasser Kinder: [Element: <vorname/>]
Verfasser Kinder: [Element: <nachname/>]

Als Ergebnis hätte ich es gerne ohne die Klammern und spitzen.


Geschafft:

Java:
System.out.println("Verfasser Kinder: " + ((Element) benannteKinder.get(0)).getChildren().get(0).getName());
            System.out.println("Verfasser Kinder: " + ((Element) benannteKinder.get(0)).getChildren().get(1).getName());

Ausgabe:

Code:
Verfasser Kinder: vorname
Verfasser Kinder: nachname

Mi
 
Zuletzt bearbeitet:

MiMa

Top Contributor
Die XML-Datei, die ich jetzt mal erstellt habe ist relativ kurz.
Wenn eine andere XML eingelesen wird, die länger ist, so bildet sich die Modellstruktur anders ab.

[XML]
<?xml version="1.0" encoding="UTF-8"?><collection xmlns="http://www.loc.gov/MARC21/slim">
<record type="Bibliographic">
<leader>01347pam a2200409 c 4500</leader>
<controlfield tag="001">989219313</controlfield> <?-- Kontrollnummer -->
<controlfield tag="003">DE-101</controlfield> <?-- Kontrollunmmer-Identifier -->
<controlfield tag="005">20081104235231.0</controlfield> <?-- Datum und Zeit der letzten Transaktion -->
<controlfield tag="007">tu</controlfield> <?-- Physische Beschreibung "Bücher" -->
<controlfield tag="008">080617s2008 gw |||||r|||| 00||||ger </controlfield> <?-- Datenelement mit fester länge -->
<datafield tag="015" ind1=" " ind2=" "> <?-- Nummer der Nationabibliografie -->
<subfield code="a">08,A46,0093</subfield> <?-- -->
<subfield code="z">08,N27,0049</subfield> <?-- -->
<subfield code="2">dnb</subfield> <?-- -->
</datafield>
<datafield tag="016" ind1="7" ind2=" "> <?-- Kontrollnummer der Nationalen Bibliografischen Stelle -->
<subfield code="2">DE-101</subfield> <?-- erste Stelle -->
<subfield code="a">989219313</subfield> <?-- zweite Stelle -->
</datafield>
<datafield tag="020" ind1=" " ind2=" "> <?-- Internationale Standardbuchnummer -->
<subfield code="a">9783834805690</subfield> <?-- xx Internationale Standardbuchnumer -->
<subfield code="c">kart. : EUR 19.90</subfield> <?-- xx Bezugsbedingungen -->
<subfield code="9">978-3-8348-0569-0</subfield> <?-- xx ISBN mit Bindestrich -->
</datafield>
<datafield tag="024" ind1="3" ind2=" "> <?-- Anderer Standard-Identifier ind1=(UPC) Universal Product Code ind2=(ISMM)International Standard Music Number -->
<subfield code="a">9783834805690</subfield> <?-- Standardnummer oder code -->
</datafield>
.....
....
...
[/XML]

Das bedeutet, das mal mehr mal weniger Daten im Modell eingelesen werden.
Also muss ich halt nur schauen, welche Daten für mich relevant sind und nach diesen im Modell suchen und entsprechend ausgeben oder in Variablen weiterverarbeiten?

Danke

Mi
 

MiMa

Top Contributor
Hi,

die ISBN benutze ich nur einmal und zwar um diese XML Datei zu finden und von der Datenbank zu holen. Die ganzen Metadaten, die ich dann lesen möchte hole ich dann anhand der Codes in das DOM Modell.

Mi
 
B

bone2

Gast
Code:
((Element) benannteKinder.get(0)).getChildren()
gibt dir eine liste von elementen die in dem element 0 enthalten sind. das ganze ist endlos verschachtelt, wo ist dein Problem?
du könntest auf jedes element dieser liste wieder jede beliebige operation für elemente ausführen, wie auch die liste alle kindelemente geben zu lassen.


wie wäre es wenn du erstmal versuchst ein leichtes xml einzulesen?
[XML]<Computer>
<Prozessor>
<Hersteller>AMD</Hersteller>
<Takt>2 GHz</Takt>
</Prozessor>
<Laufwerk Typ="CD" />
<Laufwerk Typ="HDD">
<Partition Groesse="4">C:</Partition>
<Partition Groesse="4">D:</Partition>
</Laufwerk>
<Laufwerk Typ="HDD">
<Partition Groesse="4">E:</Partition>
</Laufwerk>
<Motherboard Sockel="abc" Ramslots="3">
<Ram Groesse="4">Kingston</Ram>
<Ram Groesse="4">MSI</Ram>
<PCI>
<Grafikkarte />
<Soundkarte />
<Netzwerkkarte />
</PCI>
</Motherboard>
</Computer>[/XML]
 

MiMa

Top Contributor
Ja leichtes XML lese ich gerade ein, alles Kindelemente in der Wurzel bis auf Verfasser.
Ich taste mich da so nach und nach ran.

Und gehe dann Ebene für Ebene tiefer.

Und vor allem probiere ich alles aus.


Mi
 
Zuletzt bearbeitet:
B

bone2

Gast
Wenn du mit ner schleife über alle Kindelemente gehst, fragst du die attribute des elements ab und vergleichst die tag nummer.
passt sie, nehmen wir an du suchst nach dem preis, also tag=20, dann lässt du dir wieder alle childs für das element geben, vergleichst den code (und eventuell name) und lässt diese schleifen laufen bis du code = 9 findest. dann liest du die daten aus diesem diesem element aus.

ganz simpel :)
 

MiMa

Top Contributor
Danke,

so in etwa habe ich gedacht das es gehen sollte.
Bin halt noch Java Anfänger und bei mir dauert es halt etwas länger.

Mein Beispielprojekt habe ich zumindest erst mal soweit hinbekommen

Java:
 // Wert eines bestimmten Elementes ausgeben
            Element titelObjekt = element.getChild("titel");
            System.out.println("Titel: " + titelObjekt.getValue());
            
            Element untertitelObjekt = element.getChild("untertitel");
            System.out.println("untertitel: " + untertitelObjekt.getValue());
            
            Element inhaltObjekt = element.getChild("inhalt");
            System.out.println("Inhalt: " + inhaltObjekt.getValue());
            
            Element sachschlagwortObjekt = element.getChild("sachschlagwort");
            System.out.println("sachschlagwort: " + sachschlagwortObjekt.getValue());
            
            Element verlagnameObjekt = element.getChild("verlagname");
            System.out.println("verlagname: " + verlagnameObjekt.getValue());
            
            Element isbnObjekt = element.getChild("isbn");
            System.out.println("isbn: " + isbnObjekt.getValue());
            
            Element isbn2Objekt = element.getChild("i-s-b-n");
            System.out.println("i-s-b-n: " + isbn2Objekt.getValue());
            
            Element erscheinungsjahrObjekt = element.getChild("erscheinungsjahr");
            System.out.println("erscheinungsjahr: " + erscheinungsjahrObjekt.getValue());
            
            Element erscheinungsortObjekt = element.getChild("erscheinugsort");
            System.out.println("erscheinugsort: " + erscheinungsortObjekt.getValue());
            
            Element auflageObjekt = element.getChild("auflage");
            System.out.println("auflage: " + auflageObjekt.getValue());
            
            Element seitenObjekt = element.getChild("seiten");
            System.out.println("seiten: " + seitenObjekt.getValue());
            
            Element masseObjekt = element.getChild("masse");
            System.out.println("masse: " + masseObjekt.getValue());
            
            Element bezugsbedinnungenObjekt = element.getChild("bezugsbedinnungen");
            System.out.println("bezugsbedinnungen: " + bezugsbedinnungenObjekt.getValue());

Ausgabe:

Code:
Titel: Algorithmen kompakt und verständlich
untertitel: Lösungsstrategien am Computer
Inhalt: http://d-nb.info/989219313/04
sachschlagwort: Algorithmus
verlagname: Vieweg + Teubner
isbn: 9783834805690
i-s-b-n: 978-3-8348-0569-0
erscheinungsjahr: 2008
erscheinugsort: Wiesbaden
auflage: 1. Aufl.
seiten: VIII, 144 S.
masse: 24 cm
bezugsbedinnungen: kart. : EUR 19.90

Kleinigkeiten dauern noch etwas länger :lol:

Mi
 
Zuletzt bearbeitet:

MiMa

Top Contributor
So, soweit klappt alles. :toll:
Jetzt habe ich sogar schon die Suchabfrage mit in Java integriert und das Ergebnis wird mir in ein String-Objekt zurückgegeben.

Jetzt beginnt die eigentliche Arbeit mit dem durchlaufen der entsprechenden Tags.
Das heisst das DOM Modell wird je nach länge der XML aufgebaut, aber nur die Einträge, die mich interessieren bleiben immer gleich und die ziehe ich dann heraus.

Mi
 

MiMa

Top Contributor
Wenn du mit ner schleife über alle Kindelemente gehst, fragst du die attribute des elements ab und vergleichst die tag nummer.
passt sie, nehmen wir an du suchst nach dem preis, also tag=20, dann lässt du dir wieder alle childs für das element geben, vergleichst den code (und eventuell name) und lässt diese schleifen laufen bis du code = 9 findest. dann liest du die daten aus diesem diesem element aus.

ganz simpel :)

Das DOM Modell bietet doch einen wahlfreien Zugriff und deshalb, denke ich, das eine Schleife vielleicht nicht nötig ist?

Ich habe 16 Felder, die ich aus dem Modell entnehmen möchte und dann kann ich doch mit einem benannten Element direkt abfragen?

Also direkt zu tag="020" und das Unterlement code="c" entnehmen und in eine Instanzvariable stecken.

Das mit allen anderen Feldern genau so machen und fertig! :rtfm:

Mi
 

MiMa

Top Contributor
Naja ich denke da hatte ich etwas falsch verstanden.
Das DOM ist ja ein Baum, und durch den kommt man nur durch das ablaufen der einzelnen Knotenpunkte. :oops:

Mi
 

Templarthelast

Bekanntes Mitglied
Wenn du das Baummodell nicht magst, kannst du auch eben deinen eigenen Parser schreiben. Sowas wie:
Java:
String vorname = input.substring(input.indexOf("vorname>")+1, input.substring(input.indexOf("vorname>")+1).indexOf("<"))+input.indexOf("vorname>")
 

MiMa

Top Contributor
War halt ein Gedankenfehler.
An Bäume kommt man ja sowieso nicht herum, mann muss halt nur Üben.

Was gerade nicht so gut funktioniert.

Der Baum ist zur Zeit so:

wurzel
\--- records
\------ record
\--------- recordData
\------------ slim:record
\--------------- slimdatafield tag=20
\------------------ slimsubfield code=c
\--------------- slimdatafield tag=100
\------------------ slimsubfield code=a

Java:
// Wurzelelement erzeugen
Element wurzelElement = buchObjekt.getRootElement();
System.out.println("\nWurzelelement: " + wurzelElement.getName());
            
// Kindelemente von records, Kindelelement von der Wurzel
List recordsKinder = wurzelElement.getChildren("records");
System.out.println("Records Kinder" + recordsKinder);
            
// Kindelemente von record, Kindelement von records
List recordKinder = (List) recordsKinder.getchildren("record");
System.out.println("Record Kinder: " + recordKinder);

Einen Compilerfehler erhalte ich schon bei List record Kinder =... weil ich dort keine getChildren verwenden kann.

Bei der Ausgabe erhalte ich bei Records Kinder einfach nur []

Mi
 

MiMa

Top Contributor
Dann wollte ich mich von benannten Knoten zu benannten knoten hangeln.

Java:
// Wurzelelement erzeugen
Element wurzelElement = buchObjekt.getRootElement();
System.out.println("Wurzelelement: " + wurzelElement.getName());
            
// Nächster Vater records, Kindelelement von der Wurzel
Element recordsVater = wurzelElement.getChild("records");
System.out.println("Neuer Vater records: " + recordsVater.getName());
            
// Nächster Vater record, Kindelement von records
Element recordVater = recordsVater.getChild("record");
System.out.println("Neuer Vater record: " + recordVater.getName());

Compilerfehler gibt es nicht, nur Laufzeitfehler ?
Und zwar fängt das schon an ab hier

Java:
System.out.println("Neuer Vater records: " + recordVater.getName());

Das XML dazu sieht so aus

[XML]
<searchRetrieveResponse xmlns="http://www.loc.gov/zing/srw/">
<version>1.1</version>
<numberOfRecords>1</numberOfRecords>
<resultSetId>13488311330763034</resultSetId>
<records>
<record>
<recordSchema>MARC21-xml</recordSchema>
<recordPacking>xml</recordPacking>
<recordData>
<slim:record xmlns:slim="http://www.loc.gov/MARC21/slim" type="Bibliographic">
<slim:leader>01347pam a2200409 c 4500</slim:leader>
<slim:controlfield tag="001">989219313</slim:controlfield>
<slim:controlfield tag="003">DE-101</slim:controlfield>
<slim:controlfield tag="005">20081104235231.0</slim:controlfield>
<slim:controlfield tag="007">tu</slim:controlfield>
<slim:controlfield tag="008">080617s2008 gw |||||r|||| 00||||ger</slim:controlfield>
<slim:datafield tag="015" ind1=" " ind2=" ">
<slim:subfield code="a">08,A46,0093</slim:subfield>
<slim:subfield code="z">08,N27,0049</slim:subfield>
<slim:subfield code="2">dnb</slim:subfield>
</slim:datafield>
<slim:datafield tag="016" ind1="7" ind2=" ">
<slim:subfield code="2">DE-101</slim:subfield>
<slim:subfield code="a">989219313</slim:subfield>
</slim:datafield>
<slim:datafield tag="020" ind1=" " ind2=" ">
<slim:subfield code="a">9783834805690</slim:subfield>
<slim:subfield code="c">kart. : EUR 19.90</slim:subfield>
<slim:subfield code="9">978-3-8348-0569-0</slim:subfield>
</slim:datafield>
<slim:datafield tag="024" ind1="3" ind2=" ">
<slim:subfield code="a">9783834805690</slim:subfield>
</slim:datafield>
<slim:datafield tag="035" ind1=" " ind2=" ">
<slim:subfield code="a">(DE-599)DNB989219313</slim:subfield>
</slim:datafield>
<slim:datafield tag="035" ind1=" " ind2=" ">
<slim:subfield code="a">(OCoLC)723982056</slim:subfield>
</slim:datafield>
<slim:datafield tag="040" ind1=" " ind2=" ">
<slim:subfield code="a">1245</slim:subfield>
<slim:subfield code="b">ger</slim:subfield>
<slim:subfield code="c">DE-101</slim:subfield>
<slim:subfield code="d">9999</slim:subfield>
<slim:subfield code="e">rakwb</slim:subfield>
</slim:datafield>
<slim:datafield tag="041" ind1=" " ind2=" ">
<slim:subfield code="a">ger</slim:subfield>
</slim:datafield>
<slim:datafield tag="044" ind1=" " ind2=" ">
<slim:subfield code="c">XA-DE-HE</slim:subfield>
</slim:datafield>
<slim:datafield tag="082" ind1="0" ind2="4">
<slim:subfield code="8">1\x</slim:subfield>
<slim:subfield code="a">005.1</slim:subfield>
<slim:subfield code="q">DE-101</slim:subfield>
<slim:subfield code="2">22/ger</slim:subfield>
</slim:datafield>
<slim:datafield tag="084" ind1=" " ind2=" ">
<slim:subfield code="a">004</slim:subfield>
<slim:subfield code="q">DE-101</slim:subfield>
<slim:subfield code="2">sdnb</slim:subfield>
</slim:datafield>
<slim:datafield tag="085" ind1=" " ind2=" ">
<slim:subfield code="8">1\x</slim:subfield>
<slim:subfield code="b">005.1</slim:subfield>
</slim:datafield>
<slim:datafield tag="090" ind1=" " ind2=" ">
<slim:subfield code="a">b</slim:subfield>
</slim:datafield>
<slim:datafield tag="100" ind1="1" ind2=" ">
<slim:subfield code="0">(DE-588)136269087</slim:subfield>
<slim:subfield code="0">(DE-101)136269087</slim:subfield>
<slim:subfield code="a">Rimscha, Markus ˜vonœ</slim:subfield>
<slim:subfield code="4">aut</slim:subfield>
</slim:datafield>
<slim:datafield tag="245" ind1="1" ind2="0">
<slim:subfield code="a">Algorithmen kompakt und verständlich</slim:subfield>
<slim:subfield code="b">Lösungsstrategien am Computer</slim:subfield>
<slim:subfield code="c">Markus von Rimscha</slim:subfield>
</slim:datafield>
<slim:datafield tag="250" ind1=" " ind2=" ">
<slim:subfield code="a">1. Aufl.</slim:subfield>
</slim:datafield>
<slim:datafield tag="259" ind1=" " ind2=" ">
<slim:subfield code="a">11</slim:subfield>
</slim:datafield>
<slim:datafield tag="260" ind1="3" ind2=" ">
<slim:subfield code="a">Wiesbaden</slim:subfield>
<slim:subfield code="b">Vieweg + Teubner</slim:subfield>
<slim:subfield code="c">2008</slim:subfield>
</slim:datafield>
<slim:datafield tag="300" ind1=" " ind2=" ">
<slim:subfield code="a">VIII, 144 S.</slim:subfield>
<slim:subfield code="b">Ill., graph. Darst.</slim:subfield>
<slim:subfield code="c">24 cm</slim:subfield>
</slim:datafield>
<slim:datafield tag="490" ind1="0" ind2=" ">
<slim:subfield code="a">Studium</slim:subfield>
</slim:datafield>
<slim:datafield tag="490" ind1="0" ind2=" ">
<slim:subfield code="a">Online plus</slim:subfield>
</slim:datafield>
<slim:datafield tag="500" ind1=" " ind2=" ">
<slim:subfield code="a">Literaturverz. S. 137 - 141</slim:subfield>
</slim:datafield>
<slim:datafield tag="650" ind1=" " ind2="7">
<slim:subfield code="0">(DE-588)4001183-5</slim:subfield>
<slim:subfield code="0">(DE-101)040011836</slim:subfield>
<slim:subfield code="a">Algorithmus</slim:subfield>
<slim:subfield code="2">gnd</slim:subfield>
</slim:datafield>
<slim:datafield tag="689" ind1="0" ind2="0">
<slim:subfield code="0">(DE-588)4001183-5</slim:subfield>
<slim:subfield code="0">(DE-101)040011836</slim:subfield>
<slim:subfield code="D">s</slim:subfield>
<slim:subfield code="a">Algorithmus</slim:subfield>
</slim:datafield>
<slim:datafield tag="689" ind1="0" ind2=" ">
<slim:subfield code="5">DE-101</slim:subfield>
<slim:subfield code="5">DE-101</slim:subfield>
</slim:datafield>
<slim:datafield tag="856" ind1="4" ind2="2">
<slim:subfield code="m">B:DE-101</slim:subfield>
<slim:subfield code="q">application/pdf</slim:subfield>
<slim:subfield code="u">http://d-nb.info/989219313/04</slim:subfield>
<slim:subfield code="3">Inhaltsverzeichnis</slim:subfield>
</slim:datafield>
<slim:datafield tag="925" ind1="r" ind2=" ">
<slim:subfield code="a">ra</slim:subfield>
</slim:datafield>
</slim:record>
</recordData>
<recordPosition>1</recordPosition>
</record>
</records>
<nextRecordPosition>2</nextRecordPosition>
<echoedSearchRetrieveRequest>
<version>1.1</version>
<query>NUM=9783834805690</query>
<xQuery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
<recordSchema>MARC21-xml</recordSchema>
</echoedSearchRetrieveRequest>
<extraResponseData>
<accountOf xmlns="">Madej SRU</accountOf>
</extraResponseData>
</searchRetrieveResponse>
[/XML]

Fehler:

Code:
<slim:leader>01347pam a2200409 c 4500</slim:leader>
<slim:controlfield tag="001">989219313</slim:controlfield>
Exception in thread "main" java.lang.NullPointerException[/COLOR]
<slim:controlfield tag="003">DE-101</slim:controlfield>
<slim:controlfield tag="005">20081104235231.0</slim:controlfield>
<slim:controlfield tag="007">tu</slim:controlfield>
<slim:controlfield tag="008">080617s2008 gw |||||r|||| 00||||ger</slim:controlfield>
<slim:datafield tag="015" ind1=" " ind2=" ">
<slim:subfield code="a">08,A46,0093</slim:subfield>
<slim:subfield code="z">08,N27,0049</slim:subfield>
<slim:subfield code="2">dnb</slim:subfield>
</slim:datafield>
<slim:datafield tag="016" ind1="7" ind2=" ">
<slim:subfield code="2">DE-101</slim:subfield>
<slim:subfield code="a">989219313</slim:subfield>
</slim:datafield>
<slim:datafield tag="020" ind1=" " ind2=" ">
	at JDOMBuchAbfrage.main[/COLOR](<slim:subfield code="a">9783834805690</slim:subfield>
JDOMBuchAbfrage.java:52)
<slim:subfield code="c">kart. : EUR 19.90</slim:subfield>
<slim:subfield code="9">978-3-8348-0569-0</slim:subfield>

Vielen Dank

Mi
 
Zuletzt bearbeitet:

MiMa

Top Contributor
Die Zeile 52 ist diese hier

Java:
System.out.println("Neuer Vater records: " + recordsVater.getName());

zurückgeben müsste eigentlich "records" werden ???:L

Mi
 

MiMa

Top Contributor
Ich habe das mal an meinem Beispielprojekt Buch gemacht mit einer anderen XML und da klappt es

Java:
// Verfasser
Element verfasserObjekt = element.getChild("verfasser");
System.out.println("Verfasser: " + verfasserObjekt.getName());
            
// Element Vorname, Kindobjekt von Verfasser
Element vornameObjekt = verfasserObjekt.getChild("vorname");
System.out.println("Vorname: " + vornameObjekt.getName());
System.out.println("Vorname Inhalt: " + vornameObjekt.getValue());

Dann muss irgendetwas in der XML sein?


Mi
 
Zuletzt bearbeitet:

MiMa

Top Contributor
So, :(
es liegt an der XML.

Ich habe den gleichen Code mal mit dieser XML getestet.

[XML]
<?xml version="1.0" encoding="UTF-8"?>
<buch>
<titel>Algorithmen kompakt und verständlich</titel>
<untertitel>Lösungsstrategien am Computer</untertitel>
<inhalt>http://d-nb.info/989219313/04</inhalt>
<records>
<record></record>
</records>
<sachschlagwort>Algorithmus</sachschlagwort>
<masse>24 cm</masse>
<bezugsbedinnungen>kart. : EUR 19.90</bezugsbedinnungen>
</buch>
[/XML]

Die Ausgabe erfolgt wie erwartet:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<buch>
    <titel>Algorithmen kompakt und verständlich</titel>
    <untertitel>Lösungsstrategien am Computer</untertitel>
    <inhalt>http://d-nb.info/989219313/04</inhalt>
    <records>
        <record />
    </records>
    <sachschlagwort>Algorithmus</sachschlagwort>
    <masse>24 cm</masse>
    <bezugsbedinnungen>kart. : EUR 19.90</bezugsbedinnungen>
</buch>
Wurzelelement: buch
Neuer Vater records: records
Neuer Vater record: record

Ich bin mit XML noch nicht so gut vertraut, aber mir ist dann aufgefallen, das die abgefragte XML Datei anders beginnt.

[XML]
<searchRetrieveResponse xmlns="http://www.loc.gov/zing/srw/">
<version>1.1</version>
<numberOfRecords>1</numberOfRecords>
<resultSetId>13488311330763034</resultSetId>
<records>
<record>
<recordSchema>MARC21-xml</recordSchema>
<recordPacking>xml</recordPacking>
<recordData>
<slim:record xmlns:slim="http://www.loc.gov/MARC21/slim" type="Bibliographic">
<slim:leader>01347pam a2200409 c 4500</slim:leader>
<slim:controlfield tag="001">989219313</slim:controlfield>
<slim:controlfield tag="003">DE-101</slim:controlfield>
<slim:controlfield tag="005
...
...
[/XML]

Es beginnt mit XML Namespace, so wie ich herausgefunden habe.
Muss diese umkonvertiert werden, oder ist die Navigation hier anders ?

Vielen Dank

Mi
 

MiMa

Top Contributor
Muss ich um das Parsen zu können eine Dokumenttypdefinition (DTD)oder ein XML-Schema haben?

Geht das dann immer noch mit DOM, oder muss ich dann doch wieder auf das JAX zurück und versuchen zu verstehen wie das funktioniert?

Danke

Mi
 

MiMa

Top Contributor
Kann mir jemand helfen, bei einem kleinen Beispiel mit JAXB?

Ich habe Schwierigkeiten zu verstehen, wie das mit dem Schema, Annotationen, Unmarshalling und den Zugriff auf die Objekte funktioniert.

Ich habe im Buch und im Netz gelesen, aber so richtig verstehen, tu ich das nicht ???:L

Danke
Mi
 

MiMa

Top Contributor
Hallo,

ich bin immer noch dran den XML Inhalt aus zu werten.

Hier mal einen Auszug

Java:
Document buchObjekt = null;
String isbn13 = "9783834805690";
        
String secretToken = "xxxXXXxxxXXXxxxXXXxxxXXXxxxXXXxxx";

// Sendet die Abfrage an die Datenbank und speichert das Ergebnis in sruAbfrage
String sruAbfrage = "https://services.dnb.de/sru/dnb?version=1.1&operation=searchRetrieve&query=NUM%3D" + isbn13 + "&recordSchema=MARC21-xml&accessToken=" + secretToken;     
        
// Rückgabeobjekt
String buchRueckgabe = new String(sruAbfrage);

Das bedeutet ich sende eine Abfrage und erhalte eine XML Datei zurück, die direkt in den String sruAbfrage gespeichert wird.

Ich bin mir jetzt nicht mehr sicher, ob ich da ein XML mit einer DTD, Schema brauche um teile des Inhaltes in Java Objekte zu speichern.

Mit dem DOM Modell habe ich es versucht und konnte da nicht Navigieren.
Ist jetzt die Frage was mache ich mit dem Inhalt der String Variable, die ein XML Format enthält?

Da ich nicht alle Informationen daraus benötige, hatte ich gedacht mit einer DTD informationen zu excluden.

Die letzten 20 Tage habe ich mit XML Grundlagen und DTDs verbracht und konnte schon Ergebnisse erzielen, aber habe nicht so den richtigen durchblick was mir das bringen soll?

Zur Zeit habe ich keinen Plan, wie ich da weiter verfahren soll.

Über einen Tipp würde ich mich sehr freuen.

Danke
Mi
 
Zuletzt bearbeitet:

ARadauer

Top Contributor
Mit dem DOM Modell habe ich es versucht und konnte da nicht Navigieren.
warum? Wo war das Problem?

Poste mal das XML das raus kommt? Wo genau liegt dein Problem, wenn du so Probleme mit der Verarbeitung hast, warum machst du es nicht einfach mit String Operationen?
Du denkst zu kompliziert... gibt viele Arten wie du die Daten da aus dem String raus hohlen kannst...
 

MiMa

Top Contributor
Ich denke das es vielleicht XML Inhalte gibt, die man nicht mit dem DOM Modell verarbeiten kann ??

Programm:

Java:
import java.io.IOException;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.XMLOutputter;

public class JDOMBuchAbfrage
{
    public static void main(String[] args)
    {
        
        // initialisieren JDOM Objekt
        Document buchObjekt = null;
        
        String sruAbfrage = "TokenAbfrage.xml";
        
        // Objekt Erzeugen
        String buchRueckgabe = new String(sruAbfrage);
        try
        {
            // Das SAX Buch-Dokument erstellen
            SAXBuilder jdomBuchXML = new SAXBuilder();
            
            // JDOM Objekt den Inhalt der XML einlesen
            buchObjekt = jdomBuchXML.build(buchRueckgabe);
            
            // Wurzelelement erzeugen
            Element wurzelElement = buchObjekt.getRootElement();
            System.out.println("Wurzelelement: " + wurzelElement.getName());
            
            // Nächster Vater records, Kindelelement von der Wurzel
            Element recordsVater = wurzelElement.getChild("records");
            System.out.println("Neuer Vater records: " + recordsVater.getName());
            
            // Nächster Vater record, Kindelement von records
            Element recordVater = recordsVater.getChild("record");
            System.out.println("Neuer Vater record: " + recordVater.getName());
        }
        catch (JDOMException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

Tokenabfrage.xml

[XML]<searchRetrieveResponse xmlns="http://www.loc.gov/zing/srw/">
<version>1.1</version>
<numberOfRecords>1</numberOfRecords>
<resultSetId>13488311330763034</resultSetId>
<records>
<record>
<recordSchema>MARC21-xml</recordSchema>
<recordPacking>xml</recordPacking>
<recordData>
<slim:record xmlns:slim="http://www.loc.gov/MARC21/slim" type="Bibliographic">
<slim:leader>01347pam a2200409 c 4500</slim:leader>
<slim:controlfield tag="001">989219313</slim:controlfield>
<slim:controlfield tag="003">DE-101</slim:controlfield>
<slim:controlfield tag="005">20081104235231.0</slim:controlfield>
<slim:controlfield tag="007">tu</slim:controlfield>
<slim:controlfield tag="008">080617s2008 gw |||||r|||| 00||||ger</slim:controlfield>
<slim:datafield tag="015" ind1=" " ind2=" ">
<slim:subfield code="a">08,A46,0093</slim:subfield>
<slim:subfield code="z">08,N27,0049</slim:subfield>
<slim:subfield code="2">dnb</slim:subfield>
</slim:datafield>
<slim:datafield tag="016" ind1="7" ind2=" ">
<slim:subfield code="2">DE-101</slim:subfield>
<slim:subfield code="a">989219313</slim:subfield>
</slim:datafield>
<slim:datafield tag="020" ind1=" " ind2=" ">
<slim:subfield code="a">9783834805690</slim:subfield>
<slim:subfield code="c">kart. : EUR 19.90</slim:subfield>
<slim:subfield code="9">978-3-8348-0569-0</slim:subfield>
</slim:datafield>
<slim:datafield tag="024" ind1="3" ind2=" ">
<slim:subfield code="a">9783834805690</slim:subfield>
</slim:datafield>
<slim:datafield tag="035" ind1=" " ind2=" ">
<slim:subfield code="a">(DE-599)DNB989219313</slim:subfield>
</slim:datafield>
<slim:datafield tag="035" ind1=" " ind2=" ">
<slim:subfield code="a">(OCoLC)723982056</slim:subfield>
</slim:datafield>
<slim:datafield tag="040" ind1=" " ind2=" ">
<slim:subfield code="a">1245</slim:subfield>
<slim:subfield code="b">ger</slim:subfield>
<slim:subfield code="c">DE-101</slim:subfield>
<slim:subfield code="d">9999</slim:subfield>
<slim:subfield code="e">rakwb</slim:subfield>
</slim:datafield>
<slim:datafield tag="041" ind1=" " ind2=" ">
<slim:subfield code="a">ger</slim:subfield>
</slim:datafield>
<slim:datafield tag="044" ind1=" " ind2=" ">
<slim:subfield code="c">XA-DE-HE</slim:subfield>
</slim:datafield>
<slim:datafield tag="082" ind1="0" ind2="4">
<slim:subfield code="8">1\x</slim:subfield>
<slim:subfield code="a">005.1</slim:subfield>
<slim:subfield code="q">DE-101</slim:subfield>
<slim:subfield code="2">22/ger</slim:subfield>
</slim:datafield>
<slim:datafield tag="084" ind1=" " ind2=" ">
<slim:subfield code="a">004</slim:subfield>
<slim:subfield code="q">DE-101</slim:subfield>
<slim:subfield code="2">sdnb</slim:subfield>
</slim:datafield>
<slim:datafield tag="085" ind1=" " ind2=" ">
<slim:subfield code="8">1\x</slim:subfield>
<slim:subfield code="b">005.1</slim:subfield>
</slim:datafield>
<slim:datafield tag="090" ind1=" " ind2=" ">
<slim:subfield code="a">b</slim:subfield>
</slim:datafield>
<slim:datafield tag="100" ind1="1" ind2=" ">
<slim:subfield code="0">(DE-588)136269087</slim:subfield>
<slim:subfield code="0">(DE-101)136269087</slim:subfield>
<slim:subfield code="a">Rimscha, Markus ˜vonœ</slim:subfield>
<slim:subfield code="4">aut</slim:subfield>
</slim:datafield>
<slim:datafield tag="245" ind1="1" ind2="0">
<slim:subfield code="a">Algorithmen kompakt und verständlich</slim:subfield>
<slim:subfield code="b">Lösungsstrategien am Computer</slim:subfield>
<slim:subfield code="c">Markus von Rimscha</slim:subfield>
</slim:datafield>
<slim:datafield tag="250" ind1=" " ind2=" ">
<slim:subfield code="a">1. Aufl.</slim:subfield>
</slim:datafield>
<slim:datafield tag="259" ind1=" " ind2=" ">
<slim:subfield code="a">11</slim:subfield>
</slim:datafield>
<slim:datafield tag="260" ind1="3" ind2=" ">
<slim:subfield code="a">Wiesbaden</slim:subfield>
<slim:subfield code="b">Vieweg + Teubner</slim:subfield>
<slim:subfield code="c">2008</slim:subfield>
</slim:datafield>
<slim:datafield tag="300" ind1=" " ind2=" ">
<slim:subfield code="a">VIII, 144 S.</slim:subfield>
<slim:subfield code="b">Ill., graph. Darst.</slim:subfield>
<slim:subfield code="c">24 cm</slim:subfield>
</slim:datafield>
<slim:datafield tag="490" ind1="0" ind2=" ">
<slim:subfield code="a">Studium</slim:subfield>
</slim:datafield>
<slim:datafield tag="490" ind1="0" ind2=" ">
<slim:subfield code="a">Online plus</slim:subfield>
</slim:datafield>
<slim:datafield tag="500" ind1=" " ind2=" ">
<slim:subfield code="a">Literaturverz. S. 137 - 141</slim:subfield>
</slim:datafield>
<slim:datafield tag="650" ind1=" " ind2="7">
<slim:subfield code="0">(DE-588)4001183-5</slim:subfield>
<slim:subfield code="0">(DE-101)040011836</slim:subfield>
<slim:subfield code="a">Algorithmus</slim:subfield>
<slim:subfield code="2">gnd</slim:subfield>
</slim:datafield>
<slim:datafield tag="689" ind1="0" ind2="0">
<slim:subfield code="0">(DE-588)4001183-5</slim:subfield>
<slim:subfield code="0">(DE-101)040011836</slim:subfield>
<slim:subfield code="D">s</slim:subfield>
<slim:subfield code="a">Algorithmus</slim:subfield>
</slim:datafield>
<slim:datafield tag="689" ind1="0" ind2=" ">
<slim:subfield code="5">DE-101</slim:subfield>
<slim:subfield code="5">DE-101</slim:subfield>
</slim:datafield>
<slim:datafield tag="856" ind1="4" ind2="2">
<slim:subfield code="m">B:DE-101</slim:subfield>
<slim:subfield code="q">application/pdf</slim:subfield>
<slim:subfield code="u">http://d-nb.info/989219313/04</slim:subfield>
<slim:subfield code="3">Inhaltsverzeichnis</slim:subfield>
</slim:datafield>
<slim:datafield tag="925" ind1="r" ind2=" ">
<slim:subfield code="a">ra</slim:subfield>
</slim:datafield>
</slim:record>
</recordData>
<recordPosition>1</recordPosition>
</record>
</records>
<nextRecordPosition>2</nextRecordPosition>
<echoedSearchRetrieveRequest>
<version>1.1</version>
<query>NUM=9783834805690</query>
<xQuery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
<recordSchema>MARC21-xml</recordSchema>
</echoedSearchRetrieveRequest>
<extraResponseData>
<accountOf xmlns="">Madej SRU</accountOf>
</extraResponseData>
</searchRetrieveResponse>
[/XML]

Ich wollte die Knoten auslesen und erhalte folgende Meldungen

Code:
run:
Wurzelelement: searchRetrieveResponse
Exception in thread "main" java.lang.NullPointerException
	at JDOMBuchAbfrage.main(JDOMBuchAbfrage.java:47)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)

Das Wurzelelement wird korrekt angezeigt.

Die Zeile java:47 ist die hier

Java:
System.out.println("Neuer Vater records: " + recordsVater.getName());
Das ist die Ausgabe des nächsten Knotens.

Ich habe auch mal die System.out Anweisungend der nächsten Vaterknoten auskommentiert.
Der Vaterknoten "records" machte dann keine Probleme bei der Ausführung des Codes.
Der Vaterknoten "record" machte dann aber doch Probleme.

Mi
 
Zuletzt bearbeitet:

MiMa

Top Contributor
Ich denke, ich werde mal SAX Beispiele suchen und damit mal herum experimentieren.
Es wäre vielleicht auch schneller und Ressourcen schonender, wenn man den Stream mit Ereignissen auswertet und nur die Informationen behält, die man dabei heraus filtert.

Mi
 

MiMa

Top Contributor
Hi,

ich denke ich bin jetzt auf der richtigen Spur.
Ich habe alles gut lösen können, sobald in der XML keine Attribute vorkamen.

Jetzt habe ich mal einen Auszug einer XML Datei mit Attributen gemacht um mal zu sehen, ob ich in die richtige Richtung laufe.

Da sind jetzt noch keine Namespace drin, aber zumindest Attribute und Zeichenketten.
Auch habe ich mal die Variablen ausgegeben, um zu sehen, was da überhaupt so drin steht.

Die XML:
[XML]
<?xml version="1.0"?>
<searchRetrieveResponsesearchRetrieveResponse>
<records>
<record>
<recordData>
<datafield>
<isbn13 code="20">9783834805690</isbn13>
<bezug code="30">kart. : EUR 19.90</bezug>
<isbn15 code="40">978-3-8348-0569-0</isbn15>
</datafield>
</recordData>
</record>
</records>
</searchRetrieveResponsesearchRetrieveResponse>
[/XML]

Die Java Klasse:

Java:
/* Entwurf einer SAX Anwendung */

package Bibliothek;

import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;

import java.io.*;

// Klasse als Erweiterung der Basisklasse DefaultHandler
public class SaxEntwurf extends DefaultHandler
{
    // Variablendefinition
    private String isbn13;
    private String isbn15;
    private String bezug;
    
    /* 
     * Methoden des ContentHandlers
     */
    
    // wird vom Parser ausgeführt, wenn er den Anfang des XML Dokumentes findet
    public void startDocument() throws SAXException
    {
        System.out.println("Beginn der XML-Auswertung");
    }
    
    // wird vom Parser jedesmal aufgerufen, wenn ein Start-Tag gefunden wird
    public void startElement(String namespaceURI, String localName, String qName,
                Attributes attr) throws SAXException
    {
        // System.out.println("Es wurde ein Start-Tag gefunden");
        System.out.println("Start-Tag namespaceURI: " + namespaceURI);
        System.out.println("Start-Tag localName   : " + localName);
        System.out.println("Start-Tag qName       : " + qName);
        System.out.println("Start-Tag Attribut    : " + attr);
    }
    
    // liefert Zeichendaten von Elementen, die keine Kindelemente enthalten
    public void characters(char[] ch, int start, int length) throws SAXException
    {
        if (length > 0)
        {
            String zeichenkette = new String(ch, start, length);
            System.out.println("Die Zeichenkette ist: " + zeichenkette);
        }
    }
    
    // wird vom Parser jedesmal aufgerufen, wenn ein end-Tag gefunden wird
    public void endElement(String namespaceURI, String localName, 
                String qName) throws SAXException
    {
        // System.out.println("Es wurde ein End-Tag gefunden");
        System.out.println("End-Tag namespaceURI: " + namespaceURI);
        System.out.println("End-Tag localName   : " + localName);
        System.out.println("End-Tag qName       : " + qName);
    }
    
    // wird vom Parser aufgerufen, wenn das Ende des Dokumentes gemeldet wurde
    public void endDocument() throws SAXException
    {
        System.out.println("Ende der XML-Auswertung");
    }
    
    // Zugriff und Umwandlung der Datenquelle wenn von einer Datei gelesen wird
    private static String convertToFileURL(String filename)
    {
        // path = file.toURL().toString()
        String path = new File(filename).getAbsolutePath();
        if (File.separatorChar != '/')
        {
            path = path.replace(File.separatorChar, '/');
        }
        if (!path.startsWith("/"))
        {
            path = "/" + path;
        }
        return "file:" + path;
    }
    
    // Start der Verarbeitung des Dokumentes (Aufruf des Parsers)
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException
    {
        String filename = "src/Bibliothek/testbuch.xml";
        
        // Start des Parsens Prozesses durch erzeugen einer Factory
        SAXParserFactory saxFactory = SAXParserFactory.newInstance();
        
        // Konfiguration der Factory
        saxFactory.setNamespaceAware(true);
        
        // Durch die Factory eine neue Instnaz der Klasse JAXParser erzeugen
        SAXParser saxParser = saxFactory.newSAXParser();
        
        // XMLReader-Schittstelle durch Methode getXMLReader()
        XMLReader xmlReader = saxParser.getXMLReader();
        
        // Registriert die Schnittstelle ContentHandler beim XMLReader und gibt
        // die aktuelle Anwendung SaxEntwurf als Klasse an, die über Parser-
        // Ereignisse zu informieren ist. Es wird mit new eine Instnaz erzeugt 
        // und damit ein hadnlunfsfähiges Objekt erzeugt, damit die deklarierten
        // Methoden zum Einsatz kommen kann.
        xmlReader.setContentHandler(new SaxEntwurf());
        
        // Registrierung der Fehlerbehandlungen
        // xmlReader.setErrorHandler(new FehlerHandler(System.err));
        
        // Der XMLReader erhält den Auftrag das XML-Dokument zu parsen
        xmlReader.parse(convertToFileURL(filename));
    }
}

Und die Ausgabe:

Beginn der XML-Auswertung
Start-Tag namespaceURI:
Start-Tag localName : searchRetrieveResponsesearchRetrieveResponse
Start-Tag qName : searchRetrieveResponsesearchRetrieveResponse
Start-Tag Attribut : com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser$AttributesProxy@2a8f5fc2
Die Zeichenkette ist:

Start-Tag namespaceURI:
Start-Tag localName : records
Start-Tag qName : records
Start-Tag Attribut : com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser$AttributesProxy@2a8f5fc2
Die Zeichenkette ist:

Start-Tag namespaceURI:
Start-Tag localName : record
Start-Tag qName : record
Start-Tag Attribut : com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser$AttributesProxy@2a8f5fc2
Die Zeichenkette ist:

Start-Tag namespaceURI:
Start-Tag localName : recordData
Start-Tag qName : recordData
Start-Tag Attribut : com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser$AttributesProxy@2a8f5fc2
Die Zeichenkette ist:

Start-Tag namespaceURI:
Start-Tag localName : datafield
Start-Tag qName : datafield
Start-Tag Attribut : com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser$AttributesProxy@2a8f5fc2
Die Zeichenkette ist:

Start-Tag namespaceURI:
Start-Tag localName : isbn13
Start-Tag qName : isbn13
Start-Tag Attribut : com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser$AttributesProxy@2a8f5fc2
Die Zeichenkette ist: 9783834805690
End-Tag namespaceURI:
End-Tag localName : isbn13
End-Tag qName : isbn13
Die Zeichenkette ist:

Start-Tag namespaceURI:
Start-Tag localName : bezug
Start-Tag qName : bezug
Start-Tag Attribut : com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser$AttributesProxy@2a8f5fc2
Die Zeichenkette ist: kart. : EUR 19.90
End-Tag namespaceURI:
End-Tag localName : bezug
End-Tag qName : bezug
Die Zeichenkette ist:

Start-Tag namespaceURI:
Start-Tag localName : isbn15
Start-Tag qName : isbn15
Start-Tag Attribut : com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser$AttributesProxy@2a8f5fc2
Die Zeichenkette ist: 978-3-8348-0569-0
End-Tag namespaceURI:
End-Tag localName : isbn15
End-Tag qName : isbn15
Die Zeichenkette ist:

End-Tag namespaceURI:
End-Tag localName : datafield
End-Tag qName : datafield
Die Zeichenkette ist:

End-Tag namespaceURI:
End-Tag localName : recordData
End-Tag qName : recordData
Die Zeichenkette ist:

End-Tag namespaceURI:
End-Tag localName : record
End-Tag qName : record
Die Zeichenkette ist:

End-Tag namespaceURI:
End-Tag localName : records
End-Tag qName : records
Die Zeichenkette ist:

End-Tag namespaceURI:
End-Tag localName : searchRetrieveResponsesearchRetrieveResponse
End-Tag qName : searchRetrieveResponsesearchRetrieveResponse
Ende der XML-Auswertung
BUILD SUCCESSFUL (total time: 0 seconds)

Ich denke das sieht vielversprechend aus.

Wenn mir jemand mal einen Tip gibt wie man das mit den Attributen hin bekommt, würde ich mich sehr freuen.

Danke
Mi
 

ARadauer

Top Contributor
ich würd etwas objektorientierter denken. du willst ja irgendetwas aus dem ergenis auslesen und damit weiterarbeiten? Was ist das? Man könnte sich zb ein Ergebnis Objekt bauen...
mal als Beispiel:

Java:
public class SearchResult {

	private String isbn13;
	private String isbn13Code;
	private String isbn15;
	private String bezug;

	public String getIsbn13() {
		return isbn13;
	}

	public void setIsbn13(String isbn13) {
		this.isbn13 = isbn13;
	}

	public String getIsbn13Code() {
		return isbn13Code;
	}

	public void setIsbn13Code(String isbn13Code) {
		this.isbn13Code = isbn13Code;
	}

	public String getIsbn15() {
		return isbn15;
	}

	public void setIsbn15(String isbn15) {
		this.isbn15 = isbn15;
	}

	public String getBezug() {
		return bezug;
	}

	public void setBezug(String bezug) {
		this.bezug = bezug;
	}

	@Override
	public String toString() {
		return "SearchResult [isbn13=" + isbn13 + ", isbn13Code=" + isbn13Code + ", isbn15=" + isbn15 + ", bezug=" + bezug + "]";
	}

}

Dann kann man im Handler schön auf die Ereignisse reagieren und das Ergebnis Objekt füllen...

zb so... das geht natürlich noch sauberer... aber sax ist auch schon etwas älter und ich mach das sonst auch nie so...

Java:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class SaxEntwurf extends DefaultHandler {

	private SearchResult currentResult;
	private List<SearchResult> results;
	String currentValue;

	public void startDocument() throws SAXException {
		System.out.println("Beginn der XML-Auswertung");
		results = new ArrayList<SearchResult>();
	}
	
	public List<SearchResult> getResults() {
		return results;
	}
	public void startElement(String namespaceURI, String localName, String qName, Attributes attr) throws SAXException {
		//bei record Data fangen wir ein neues ergebnis an...
		if("recordData".equalsIgnoreCase(localName)){
			currentResult = new SearchResult();
			results.add(currentResult);
		}
		
		//wir setzen mal nur den code von isbn13... die andern kannst du selber machen 
		for (int i = 0; i < attr.getLength(); i++) { //hier iterieren wir einfach über die attriute			
			if("isbn13".equalsIgnoreCase(localName) && "code".equalsIgnoreCase(attr.getLocalName(i))){
				currentResult.setIsbn13Code(attr.getValue(i));
			}
		}

	}

	//ist der tag zu ende kann man den aktuellen wert in die variable schreiben...
	public void endElement(String uri, String localName, String qName) throws SAXException {
		if("isbn13".equalsIgnoreCase(localName)){
			currentResult.setIsbn13(currentValue);
		}else if("isbn15".equalsIgnoreCase(localName)){
			currentResult.setIsbn15(currentValue);
		}else if("bezug".equalsIgnoreCase(localName)){
			currentResult.setBezug(currentValue);
		}
	}

	// hier bekommen wir den aktuellen wert...
	public void characters(char[] ch, int start, int length) throws SAXException {
		currentValue = new String(ch, start, length);
	}


	// Zugriff und Umwandlung der Datenquelle wenn von einer Datei gelesen wird
	private static String convertToFileURL(String filename) {
		// path = file.toURL().toString()
		String path = new File(filename).getAbsolutePath();
		if (File.separatorChar != '/') {
			path = path.replace(File.separatorChar, '/');
		}
		if (!path.startsWith("/")) {
			path = "/" + path;
		}
		return "file:" + path;
	}

	// Start der Verarbeitung des Dokumentes (Aufruf des Parsers)
	public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
		String filename = "d:/testdata.xml";

		// Start des Parsens Prozesses durch erzeugen einer Factory
		SAXParserFactory saxFactory = SAXParserFactory.newInstance();

		// Konfiguration der Factory
		saxFactory.setNamespaceAware(true);

		// Durch die Factory eine neue Instnaz der Klasse JAXParser erzeugen
		SAXParser saxParser = saxFactory.newSAXParser();

		// XMLReader-Schittstelle durch Methode getXMLReader()
		XMLReader xmlReader = saxParser.getXMLReader();

		// Registriert die Schnittstelle ContentHandler beim XMLReader und gibt
		// die aktuelle Anwendung SaxEntwurf als Klasse an, die über Parser-
		// Ereignisse zu informieren ist. Es wird mit new eine Instnaz erzeugt
		// und damit ein hadnlunfsfähiges Objekt erzeugt, damit die deklarierten
		// Methoden zum Einsatz kommen kann.
		SaxEntwurf handler = new SaxEntwurf();
		xmlReader.setContentHandler(handler);

		// Registrierung der Fehlerbehandlungen
		// xmlReader.setErrorHandler(new FehlerHandler(System.err));

		// Der XMLReader erhält den Auftrag das XML-Dokument zu parsen
		xmlReader.parse(convertToFileURL(filename));
		
		
		//wir sind fertig... ausgeben...
		System.out.println(handler.getResults().size()+" Ergebnisse");
		for(SearchResult result : handler.getResults()){
			System.out.println(result);
		}
	}
		
}

mit der liste von SearchResult kann man dann super weiterarbeiten.. in db speichern, in gui anzeigen, rechnen usw...

ich würd solche kommentare lassen...
// Variablendefinition
 

MiMa

Top Contributor
Hallo,

Da ich in den letzten 20 Tagen nur XML Grundlagen gemacht habe, brauche ich ein wenig Zeit um mein gelerntes Java Wissen wieder zu reaktivieren.

Objektorientierter wollte ich eigentlich schon programmieren und hatte auch die Klasse Buch, die ich auch schon in den vorherigen Beispielen verwendet habe.

Auszug aus Klasse "Buch.java"

Java:
/* Datenhalter für Buchdaten */

package de.michael;

public class Buch
{
    String bufferNummer;
    String bufferCode;
	
    String isbn13;
    String isbn15;
    String bezug;
     
    public String getBufferNummer()
	{
		return bufferNummer;
	}
	public void setBufferNummer(String bufferNummer)
	{
		this.bufferNummer = bufferNummer;
	}
	public String getBufferCode()
	{
		return bufferCode;
	}
	public void setBufferCode(String bufferCode)
	{
		this.bufferCode = bufferCode;
	}
	
	public String getIsbn13()
	{
		return isbn13;
	}
	public void setIsbn13(String isbn13)
	{
		this.isbn13 = isbn13;
	}
	public String getIsbn15()
	{
		return isbn15;
	}
	public void setIsbn15(String isbn15)
	{
		this.isbn15 = isbn15;
	}
	public String getBezug()
	{
		return bezug;
	}
	public void setBezug(String bezug)
	{
		this.bezug = bezug;
	}
}

Da ich Tags und Codes als Vorlage habe die zu einem Schlüssel passen, habe ich mir gedacht die Tags und Codes heraus zu lesen und dann zusammen zu setzen, um die gefundene Zeichenkette darin zu speichern.

Klasse "XMLextractorMarc21.java"

Java:
package de.michael;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

/**
 * @author Michael
 * 
 */

public class XMLextractorMarc21 extends DefaultHandler
{
	String	bufferNummer;		// Tagnummer (020, ...)
	String	bufferCode;		    // TagCode (a, b, ...)
	String	tag020codeA;		// ISBN 13 Nummer
	String	tag020codeC;		// Bezugsart
	String	tag020code9;		// ISBN 15 Nummer

	/*
	 * Default Handler Methoden
	 */

	// wird vom Parser ausgeführt, wenn er den Anfang des XML Dokumentes findet
	public void startDocument() throws SAXException
	{
		System.out.println("Beginn der XML-Auswertung");
	}

	// wird vom Parser jedesmal aufgerufen, wenn ein Start-Tag gefunden wird
	public void startElement(String namespaceURI, String localName,
			String qName, Attributes attr) throws SAXException
	{

		// Der Attributinhalt ist der orange Dargestellte Wert (020, a, b, ...)
		if (attr.getValue(0).length() > 1)
		{
			bufferNummer = attr.getValue(0);
			System.out.println("Die bufferAttributnummer ist: " + bufferNummer);
		} else
		{
			bufferCode = attr.getValue(0);
			System.out.println("Der bufferAttributCode ist: " + bufferCode);
		}
	}

	// liefert Zeichendaten von Elementen, die keine Kindelemente enthalten
	public void characters(char[] ch, int start, int length)
			throws SAXException
	{
		if (length > 0)
		{
			// Benötigte TagCodes
			// 020 ab9, 245 abc, 250 a , 260 abc, 300 abc, 490 a, 856 mqu3

			String zeichenkette = new String(ch, start, length);
			System.out.println("Die Zeichenkette ist: " + zeichenkette);

			String buchCode = bufferNummer + bufferCode;

			if ("020a".equals(buchCode))
			{
				tag020codeA = zeichenkette;
				System.out.println("Buchcode tag020codeA enthält: "
						+ tag020codeA);
			} else if ("020c".equals(buchCode))
			{
				tag020codeC = zeichenkette;
				System.out.println("Buchcode tag020codeC enthält: "
						+ tag020codeC);
			} else if ("0209".equals(buchCode))
			{
				tag020code9 = zeichenkette;
				System.out.println("Buchcode tag020code9 enthält: "
						+ tag020code9);
			}
		}
	}

	// wird vom Parser aufgerufen, wenn das Ende des Dokumentes gemeldet wurde
	public void endDocument() throws SAXException
	{
		System.out.println("Ende der XML-Auswertung");

		System.out.println("Die ISBN13 Nummer ist: " + tag020codeA);
		System.out.println("Die ISBN15 Nummer ist: " + tag020code9);
		System.out.println("Die Bezugsart ist    : " + tag020codeC);
	}

	// Zugriff und Umwandlung der Datenquelle wenn von einer Datei gelesen wird
	private static String convertToFileURL(String filename)
	{
		// path = file.toURL().toString()
		String path = new File(filename).getAbsolutePath();
		if (File.separatorChar != '/')
		{
			path = path.replace(File.separatorChar, '/');
		}
		if (!path.startsWith("/"))
		{
			path = "/" + path;
		}
		return "file:" + path;
	}

	/**
	 * @param args
	 */

	// Start der Verarbeitung des Dokumentes (Aufruf des Parsers)
	public static void main(String[] args) throws ParserConfigurationException,
			SAXException, IOException
	{
		String filename = "src/xml/buchElementMarc21.xml";

		// Start des Parsens Prozesses durch erzeugen einer Factory
		SAXParserFactory saxFactory = SAXParserFactory.newInstance();

		// Konfiguration der Factory
		saxFactory.setNamespaceAware(true);

		// Durch die Factory eine neue Instnaz der Klasse JAXParser erzeugen
		SAXParser saxParser = saxFactory.newSAXParser();

		// XMLReader-Schittstelle durch Methode getXMLReader()
		XMLReader xmlReader = saxParser.getXMLReader();

		// Registriert die Schnittstelle ContentHandler beim XMLReader und gibt
		// die aktuelle Anwendung SaxEntwurf als Klasse an, die über Parser-
		// Ereignisse zu informieren ist. Es wird mit new eine Instnaz erzeugt
		// und damit ein hadnlunfsfähiges Objekt erzeugt, damit die deklarierten
		// Methoden zum Einsatz kommen kann.
		// xmlReader.setContentHandler(new SaxEntwurf());
		xmlReader.setContentHandler(new XMLextractorMarc21());

		// Registrierung der Fehlerbehandlungen
		// xmlReader.setErrorHandler(new FehlerHandler(System.err));

		// Der XMLReader erhält den Auftrag das XML-Dokument zu parsen
		xmlReader.parse(convertToFileURL(filename));
	}
}

Um dann die komplexe XML-Datei mit Namespace usw. zu verwenden, habe ich ein Element heraus gezogen.

XML Testdatei "buchElementMarc21.xml"

[XML]
<!-- 1 Benötigtes Marc 21 Element -->
<slim:record xmlns:slim="http://www.loc.gov/MARC21/slim" type="Bibliographic">
<slim:datafield tag="020" ind1=" " ind2=" ">
<slim:subfield code="a">9783834805690</slim:subfield>
<slim:subfield code="c">kart. : EUR 19.90</slim:subfield>
<slim:subfield code="9">978-3-8348-0569-0</slim:subfield>
</slim:datafield>
</slim:record>
[/XML]

Ich erhalte mittlerweile folgende Ergebnisse:

Beginn der XML-Auswertung
Die bufferAttributnummer ist: Bibliographic
Die Zeichenkette ist:

Die bufferAttributnummer ist: 020
Die Zeichenkette ist:

Der bufferAttributCode ist: a
Die Zeichenkette ist: 9783834805690
Buchcode tag020codeA enthält: 9783834805690
Die Zeichenkette ist:

Buchcode tag020codeA enthält:

Der bufferAttributCode ist: c
Die Zeichenkette ist: kart. : EUR 19.90
Buchcode tag020codeC enthält: kart. : EUR 19.90
Die Zeichenkette ist:

Buchcode tag020codeC enthält:

Der bufferAttributCode ist: 9
Die Zeichenkette ist: 978-3-8348-0569-0
Buchcode tag020code9 enthält: 978-3-8348-0569-0
Die Zeichenkette ist:

Buchcode tag020code9 enthält:

Die Zeichenkette ist:

Buchcode tag020code9 enthält:

Ende der XML-Auswertung
Die ISBN13 Nummer ist:

Die ISBN15 Nummer ist:

Die Bezugsart ist :

Warum ich die Klasse Buch nicht verwendet habe, ist der Grund, weil , wenn ich ein Objekt in der Main Methode sagen wir (Buch buchObjekt = new Buch()) erstelle, dann in den Methoden des Parsers nicht darauf zugreifen kann.

Wenn der Parser einmal gestartet ist, dann springt dieser ja automatisch zu den Parser-Methoden.

Der Parser ruft dann immer wie folgt auf:
startDocument() Wenn er den Anfang der XML findet
startElement(.......) Wenn er ein Start-Tag findet
characters(.....) Wenn er eineZeichendaten findet, die keine Kindelemente sind
endElement() Wenn er ein End-Tag findet
.....
...
..
endDokument() Wenn das Ende der XML-Datei gefunden wurde.

Ich würde gerne die Instanzvariablen in der Buchklasse drauf zugreifen, da der Parser bis zum ende nur auf die Parser-Methoden zugreift, kann ich auf das buchObjekt nicht drauf zugreifen.

Wenn ich aber ein Buchobjekt in der Methode startElement(...) erstelle und eines in Characters(...) dan sind das zwei unterschiedliche Objekte, also das ist auch keine Lösung.

Viele Grüsse
Mi
 
Zuletzt bearbeitet:

MiMa

Top Contributor
So ich habe es mittlerweile umgebaut und verwende die Klasse Buch.

XMLExtractorMarc21.java

Java:
package de.michael;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import de.michael.Buch;

/**
 * @author Michael
 * 
 */

public class XMLextractorMarc21 extends DefaultHandler
{
	// Buchobjekt erzeugen
	Buch buchObjekt = new Buch();

	/*
	 * Default Handler Methoden
	 */

	// wird vom Parser ausgeführt, wenn er den Anfang des XML Dokumentes findet
	public void startDocument() throws SAXException
	{
		System.out.println("Beginn der XML-Auswertung");		
	}

	// wird vom Parser jedesmal aufgerufen, wenn ein Start-Tag gefunden wird
	public void startElement(String namespaceURI, String localName,
			String qName, Attributes attr) throws SAXException
	{
		// Der Attributinhalt ist der orange Dargestellte Wert (020, a, b, ...)
		if (attr.getValue(0).length() > 1)
		{
			buchObjekt.setBufferNummer(attr.getValue(0));
			System.out.println("Die bufferAttributnummer ist: " + buchObjekt.getBufferNummer());
		} else
		{
			buchObjekt.setBufferCode(attr.getValue(0));
			System.out.println("Der bufferAttributCode ist: " + buchObjekt.getBufferCode());
		}
	}

	// liefert Zeichendaten von Elementen, die keine Kindelemente enthalten
	public void characters(char[] ch, int start, int length)
			throws SAXException
	{
		if (length > 0)
		{
			// Benötigte TagCodes
			// 020 ab9, 245 abc, 250 a , 260 abc, 300 abc, 490 a, 856 mqu3

			String zeichenkette = new String(ch, start, length);
			System.out.println("Die Zeichenkette ist: " + zeichenkette);

			String buchCode = buchObjekt.getBufferNummer() + buchObjekt.getBufferCode();

			if ("020a".equals(buchCode))
			{
				buchObjekt.setIsbn13(zeichenkette);
				System.out.println("Buchcode tag020codeA enthält: "
						+ buchObjekt.getIsbn13());
			} else if ("020c".equals(buchCode))
			{
				buchObjekt.setBezug(zeichenkette);
				System.out.println("Buchcode tag020codeC enthält: "
						+ buchObjekt.getBezug());
			} else if ("0209".equals(buchCode))
			{
				buchObjekt.setIsbn15(zeichenkette);
				System.out.println("Buchcode tag020code9 enthält: "
						+ buchObjekt.getIsbn15());
			}
		}
	}

	// wird vom Parser aufgerufen, wenn das Ende des Dokumentes gemeldet wurde
	public void endDocument() throws SAXException
	{
		System.out.println("Ende der XML-Auswertung");

		System.out.println("Die ISBN13 Nummer ist: " + buchObjekt.getIsbn13());
		System.out.println("Die ISBN15 Nummer ist: " + buchObjekt.getIsbn15());
		System.out.println("Die Bezugsart ist    : " + buchObjekt.getBezug());
	}

	// Zugriff und Umwandlung der Datenquelle wenn von einer Datei gelesen wird
	private static String convertToFileURL(String filename)
	{
		// path = file.toURL().toString()
		String path = new File(filename).getAbsolutePath();
		if (File.separatorChar != '/')
		{
			path = path.replace(File.separatorChar, '/');
		}
		if (!path.startsWith("/"))
		{
			path = "/" + path;
		}
		return "file:" + path;
	}

	/**
	 * @param args
	 */

	// Start der Verarbeitung des Dokumentes (Aufruf des Parsers)
	public static void main(String[] args) throws ParserConfigurationException,
			SAXException, IOException
	{
		String filename = "src/xml/buchElementMarc21.xml";

		// Start des Parsens Prozesses durch erzeugen einer Factory
		SAXParserFactory saxFactory = SAXParserFactory.newInstance();

		// Konfiguration der Factory
		saxFactory.setNamespaceAware(true);

		// Durch die Factory eine neue Instnaz der Klasse JAXParser erzeugen
		SAXParser saxParser = saxFactory.newSAXParser();

		// XMLReader-Schittstelle durch Methode getXMLReader()
		XMLReader xmlReader = saxParser.getXMLReader();

		// Registriert die Schnittstelle ContentHandler beim XMLReader und gibt
		// die aktuelle Anwendung SaxEntwurf als Klasse an, die über Parser-
		// Ereignisse zu informieren ist. Es wird mit new eine Instnaz erzeugt
		// und damit ein hadnlunfsfähiges Objekt erzeugt, damit die deklarierten
		// Methoden zum Einsatz kommen kann.
		// xmlReader.setContentHandler(new SaxEntwurf());
		xmlReader.setContentHandler(new XMLextractorMarc21());

		// Registrierung der Fehlerbehandlungen
		// xmlReader.setErrorHandler(new FehlerHandler(System.err));

		// Der XMLReader erhält den Auftrag das XML-Dokument zu parsen
		xmlReader.parse(convertToFileURL(filename));
	}
}

Die Ausgabe ist wie folgt:

Beginn der XML-Auswertung
Die bufferAttributnummer ist: Bibliographic
Die Zeichenkette ist:

Die bufferAttributnummer ist: 020
Die Zeichenkette ist:

Der bufferAttributCode ist: a
Die Zeichenkette ist: 9783834805690
Buchcode tag020codeA enthält: 9783834805690
Die Zeichenkette ist:

Buchcode tag020codeA enthält:

Der bufferAttributCode ist: c
Die Zeichenkette ist: kart. : EUR 19.90
Buchcode tag020codeC enthält: kart. : EUR 19.90
Die Zeichenkette ist:

Buchcode tag020codeC enthält:

Der bufferAttributCode ist: 9
Die Zeichenkette ist: 978-3-8348-0569-0
Buchcode tag020code9 enthält: 978-3-8348-0569-0
Die Zeichenkette ist:

Buchcode tag020code9 enthält:

Die Zeichenkette ist:

Buchcode tag020code9 enthält:

Ende der XML-Auswertung
Die ISBN13 Nummer ist:

Die ISBN15 Nummer ist:

Die Bezugsart ist :

Auch leider werden hier die Ausgabe auf die Konsole nicht mit den Variablen ausgegeben.
Da ich aber in die Instanzvariablen schreibe und auch direkt von dort aus als Kontrolle ausgeben lasse, sollten die Werte schon richtig gespeichert worden sein?

Warum werden die Werte zum Schluss nicht ausgegeben ??

Danke
Mi.
 

ARadauer

Top Contributor
<slim:datafield tag="020"
<slim:subfield code="a">
... cobol entwickler treffen auf XML .. furchtbar...


Warum werden die Werte zum Schluss nicht ausgegeben ??
weil du sie dir wieder überschreibst...



zb hier

Buchcode tag020code9 enthält: 978-3-8348-0569-0
ok da passts noch
paar zeilen darunter
Buchcode tag020code9 enthält:

als tipp: ich würde in der characters Methode nix ins objekt schreiben sondern nur den aktuellen string in eine zwischenvariable halten und dann beim endTag in die entsprechende variable...
 
Zuletzt bearbeitet:

MiMa

Top Contributor
Hi,

ja Du hast recht, die Variable buchCode wird immer wieder überschrieben, aber je nach Inhalt, die der buchCode trägt wie "020a" wird der Inhalt der Zeichenkette in die entsprechende Instanzvariable geschrieben.
Wenn der buchCode "020a" enthält wird er durch die if Anweisungen in setIsbn13 geschrieben.
Wenn der buchCode "020c" enthält dann setBezug und bei "0209" in setIsbn15.

Da der buchCode immer andere Werte hat, überschreibt er doch dann die Inhalte des "buchObjekt" doch nicht?

Um auch noch den buchCode zu prüfen habe ich den Code so geändert, das noch der aktuelle buchCode mit ausgegeben wird.

Also wenn der Parser anfängt und den start der XML findet, dann führt er folgende Methoden aus:

Ich habe jetzt mal die XML ergänzt um mal mehr zu sehen.

[XML]
<!-- 1 Benötigtes Marc 21 Element -->
<slim:record xmlns:slim="http://www.loc.gov/MARC21/slim" type="Bibliographic">zkrecord
<slim:datafield tag="020" ind1=" " ind2=" ">zkDatafield
<slim:subfield code="a">9783834805690</slim:subfield>zkCodeA
<slim:subfield code="c">kart. : EUR 19.90</slim:subfield>zkCodeC
<slim:subfield code="9">978-3-8348-0569-0</slim:subfield>zkCode9
</slim:datafield>zkDatafieldEnd
</slim:record>
[/XML]


Und erkenne nun, das ich da total falsche Wert drin habe ;(

Mi
 

ARadauer

Top Contributor
Ich habe jetzt mal die XML ergänzt um mal mehr zu sehen.
warum veränderst du die quelle? Du willst von A mit B zu C und B geht nicht richtig.. dann würd ich nicht A verändern..

also das ist ein beispiel, dass du verarbeiten willst?

<slim:record xmlns:slim="http://www.loc.gov/MARC21/slim" type="Bibliographic">
<slim:datafield tag="020" ind1=" " ind2=" ">
<slim:subfield code="a">9783834805690</slim:subfield>
<slim:subfield code="c">kart. : EUR 19.90</slim:subfield>
<slim:subfield code="9">978-3-8348-0569-0</slim:subfield>
</slim:datafield>
</slim:record>

marc21... nicht gerade das was man als schönes xml bezeichnet.. hab mir das einwenig angesehen, aber gut das ist halt eine alte standard schnittstelle die ins xml transferiert wurde

deine überprüfung im startElement ist zu ungenau!!!! wenn der wert länger als 1 ist dann muss es tag von datefield sein und sonst ist es code vom subfield? ist nicht dein ernst oder?
Die bufferAttributnummer ist: Bibliographic
ich würd mich auch nicht drauf verlassen, das tag immer als erstes kommt, die reihenfolge von attributen ist nicht festgelegt (oder? du hast die letzen 20 tage xml bücher gelesen)

Java:
 public void startElement(String namespaceURI, String localName,
            String qName, Attributes attr) throws SAXException
    {
        // Der Attributinhalt ist der orange Dargestellte Wert (020, a, b, ...)
        if (localName.equals("datafield"))
        {
            buchObjekt.setBufferNummer(getValueFromAttribute(attr, "tag"));
            System.out.println("Die bufferAttributnummer ist: " + buchObjekt.getBufferNummer());
        } else if (localName.equals("subfield"))
        {
            buchObjekt.setBufferCode(getValueFromAttribute(attr, "code"));
            System.out.println("Der bufferAttributCode ist: " + buchObjekt.getBufferCode());
        }
    }
    
    private String getValueFromAttribute(Attributes attr, String attributeName){
    	for(int i = 0; i < attr.getLength(); i++){
    		if(attr.getLocalName(i).equals(attributeName)){
    			return attr.getValue(i);
    		}
    	}
    	return null;
    }


und du ich denke du solltest wenn das subfield tag geschlossen wurden, den code zurück setzen, dann kann es dir nicht passieren, dass irgendetwas anderes das zwischen </slim:subfield> und
</slim:datafield> steht in deine variablen geschrieben wird


Java:
	public void endElement(String uri, String localName, String qName) throws SAXException {
		if (localName.equals("datafield")) {
			buchObjekt.setBufferNummer(null);
			System.out.println("Die bufferAttributnummer ist: " + buchObjekt.getBufferNummer());
		} else if (localName.equals("subfield")) {
			buchObjekt.setBufferCode(null);
			System.out.println("Der bufferAttributCode ist: " + buchObjekt.getBufferCode());
		}
	}

Ausgabe

Beginn der XML-Auswertung
Die Zeichenkette ist:

Die bufferAttributnummer ist: 020
Die Zeichenkette ist:

Der bufferAttributCode ist: a
Die Zeichenkette ist: 9783834805690
Buchcode tag020codeA enthält: 9783834805690
Der bufferAttributCode ist: null
Die Zeichenkette ist:

Der bufferAttributCode ist: c
Die Zeichenkette ist: kart. : EUR 19.90
Buchcode tag020codeC enthält: kart. : EUR 19.90
Der bufferAttributCode ist: null
Die Zeichenkette ist:

Der bufferAttributCode ist: 9
Die Zeichenkette ist: 978-3-8348-0569-0
Buchcode tag020code9 enthält: 978-3-8348-0569-0
Der bufferAttributCode ist: null
Die Zeichenkette ist:

Die bufferAttributnummer ist: null
Die Zeichenkette ist:

Ende der XML-Auswertung
Die ISBN13 Nummer ist: 9783834805690
Die ISBN15 Nummer ist: 978-3-8348-0569-0
Die Bezugsart ist : kart. : EUR 19.90
perfekt :toll:
 

MiMa

Top Contributor
Hallo,

ich Habe die Quelle mal verändert um mal zu sehen, was sich bei der Ausgabe sonst noch so tut.
Ist halt mal was probieren und sehen gewesen und war für mich sehr aufschlussreich.

Wie das nicht schöne XML aussieht liegt leider nicht bei mir, das ist halt ein Auszug aus einem Datensatz der Deutschen National Bibliothek, so wie er zurückgegeben wird.

Die Prüfungen im start Element sind für einen langjährigen Programmierer zu ungenau. Ok, klar, das war halt das erste was mir eingefallen war, denn die Codes tragen immer nur eine Ziffer und die Tags immer 3 Ziffern. Demnach ergab sich das so. Da ich noch nicht lange Java Programmiere, wollte ich erstmal etwas funktionsfähiges sehen. Ausbaufähig und Verbesserungen sind immer möglich.

Die letzten 20 Tage habe ich XML Grundlagen gemacht und versucht zu verstehen, wie DTDs, Schema usw funktionieren. Habe aber dann festgestellt, das dies eine ziemlich komplexe Angelegenheit ist.

Da ich mit DOM schon erfolgreich war, habe ich mich dann entschlossen mit SAX mal zu probieren. Deshalb ist der code auch so entstanden, das er gerade mal so läuft.

Ich habe in den letzten Wochen ziemlich viel probieren müssen, bis ich verstanden habe, was ich überhaupt benötige um mein Problem zu lösen.

Vielen Dank für Dein Beispiel.

Mi
 
Zuletzt bearbeitet:

MiMa

Top Contributor
Ich möchte mich noch mal bei allen recht herzlich bedanken.

Das Problem zu lösen habe ich jetzt verstanden und mein XML-Testelement erfolgreich in Java Variablen geschrieben.

@ARadauer
Du hattest Recht, das nicht nur die Start-Tags zu prüfen seien, sondern auch die End-Tags und dort dann die Variablen NULL zu setzen. Ausserdem war die Abfrage zwischen Nummer und Code mit "> 1" zwar lauffähig, aber nicht gerade guter Programmierstil. Durch Dein Codebeispiel habe ich verstanden wie Wichtig es ist durch andere Parameter zu prüfen.

Vielen Dank
Mi
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
B XML-Daten mit SAX Parser verarbeiten in Java XML & JSON 4
A GUI um auf XSD Basis (valide) XML Daten zu erzeugen XML & JSON 3
K XML Datei erstellen und Daten daraus in Java auslesen XML & JSON 6
K Login Daten mit JSoup übermitteln XML & JSON 0
M JAXB @XMLID und @XMLIDREF, wie Daten hinzufügen XML & JSON 2
G Jsoup Daten lesen XML & JSON 0
P XML Daten sortieren - Verständnisfrage XML & JSON 4
F Parsen von Daten aus einer Homepage XML & JSON 6
G XML-Daten im Programm verwenden XML & JSON 5
M [XSD-Definition] Eindeutige Daten in NodeList (Bereich) XML & JSON 3
K Visualisierung von Daten XML & JSON 13
T Daten in Xml speichern XML & JSON 4
T Daten aus Programm in XML Datei speichern XML & JSON 2
X Am Server ankommende XML Daten verarbeiten XML & JSON 11
L XML Daten auslesen und in Tabelle (Array) speichern XML & JSON 1
Mike90 Daten aus DB in ExcelTabelle lesen + bearbeiten + formatieren XML & JSON 2
S Mit welcher Technologie Daten abspeichern? XML & JSON 6
J Daten werden in ArrayList geschrieben, AL nicht in .xml ? XML & JSON 5
O XML-Daten fehlen in der Darstellung XML & JSON 2
I Mit JDOM Daten aus XML in ein Array abfüllen XML & JSON 4
R Daten aus xml lesen und in Strings speichern XML & JSON 4
G XML als "Datenbank" für kleine Daten XML & JSON 2
T [JDOM] XML File, neue Daten hinzufügen XML & JSON 5
B XML aus einer URL im Internet lesen (JDOM) XML & JSON 4
N XML File aus Internet korrekt mit absätzen formatiert abspeichern XML & JSON 10

Ähnliche Java Themen

Neue Themen


Oben