XML parsen

blurry333

Mitglied
Hallo,

ich habe mehrere xml files. Jetzt soll ich rausfinden in welchen ein spezielles tag mit dem Attribut XY vorkommt. Wie würdet ihr das machen ? Mir liegen die XML Dateien schon als Objekt vor. Hab das mit Jaxb gemarshalt.
 
Zuletzt bearbeitet:

HarleyDavidson

Bekanntes Mitglied
Das lässt sich auch mit einem einfachen BufferedReader lösen.
Einfach zeilenweise einlesen und nach dem Tag suchen (und gegebenenfalls die Zeile dann ausgeben, je nachdem was passieren soll, wenn der Tag gefunden wurde).
 

blurry333

Mitglied
ja stimmt. Das ist wohl das einfachste. Wenn ich die Zeile habe muss ich aber auch erst mal schauen ob diese Zeile das Tag enthält.

Lieber wäre mir da schon ein richtiger <Tag> Leser, der alle Tags durchschaut und mir dann sagt ob es vorkommt. Keine Ahnung ob es sowas gibt.
 

DrZoidberg

Top Contributor
Wenn du nur einen einzigen Wert aus der XML Datei lesen willst, dann ist ein regulärer Ausdruck die einfachste Lösung.
Aus der ganzen Datei einen einzigen langen String machen und dann per RegEx suchen.
 

rme

Top Contributor
Man sollte auf XML-Daten niemals mit String-Operationen arbeiten, also weder mit regulären Ausdrücken, noch mit Suchfunktionen. Der Grund ist, dass XML keine reguläre Grammatik hat und deshalb mächtiger als reguläre Ausdrücke ist. Beispiel: In XML gibt es die Möglichkeit, Kommentare einzufügen - damit kann ein regulärer Ausdruck nicht umgehen, man müsste sich also erstmal mehrere Ausdrücke basteln, um erstmal kommentierte Bereiche zu erkennen.. und wenn man soweit ist, kann man es auch lieber mit einem SAXParser machen, wie von Attila vorgeschlagen. Hier ist ein Beispiel dafür:

Galileo Computing :: Java ist auch eine Insel – 18.6 Serielle Verarbeitung von XML mit SAX *

Du musst einfach nur in startElement prüfen, ob das gewünschte Attribut vorhanden ist :)
 

DrZoidberg

Top Contributor
Meine XML Datei ist ca 2500 Zeilen lang. Wie soll ich das dann machen ?

Mit anderen Worten, deine Datei ist lediglich um die 100kB gross? Das ist winzig. Wo ist da das Problem?
Du könntest z.B. alle Zeilen zu einem StringBuilder hinzufügen.
Aber wie rme schon erwähnt hat, wird bei der Methode alles durchsucht, auch auskommentierte Bereiche. Allerdings ist das in deinem Fall wahrscheinlich kein Problem.
 

rme

Top Contributor
Das halte ich für keine angemessene Herangehensweise. Gründe:

* neben den Kommentaren gibt es weitere Stolperfallen: Ein Attribut kann mit " oder mit ' angegeben werden, zwischen dem = und dem Attributwert können null bis beliebig viele Leerzeichen oder Zeilenumbrüche stehen.. der reguläre Ausdruck wäre so kompliziert, dass man ihn nach ein paar Wochen nicht mehr versteht.

* der Speicherbedarf liegt in O(n), wobei n die Größe der Datei ist. Bei einem SAX-Parser liegt sie in O(m), wobei m die maximale Verschachtelungstiefe der Tags ist.

* sobald man den Code für noch größere Dateien verwenden will, hat man ein Performance- und Speicher-Problem.

Mit regulären Ausdrücken würde ich in diesem Fall nur arbeiten, wenn du zu 100% garantieren kannst, dass du diese Dateien selbst erzeugst, die Größe in diesem Rahmen bleibt und sich das Format nicht mehr ändert. Dann verwendest du nicht XML, sondern eine Teilsprache davon, die auf viele XML-Funktionen verzichtet.

Diese Aufgabe kann man mit dem Standard-Java-SAX-Parser in weniger als 50 Zeilen lösen. Wenn du möchtest, kann ich dir gern ein Beispiel zeigen.
 

DrZoidberg

Top Contributor
Du hast natürlich Recht. Reguläre Ausdrücke für XML zu verwenden ist unprofessionell. Aber vielleicht benötigt er ja gar keine professionelle Lösung.

Hier mal die kürzeste Lösung, die mir eingefallen ist.

Java:
static String findAttribute(String fileName, String tag, String attribute) {
    try {
        String xml = new String(Files.readAllBytes(new File(fileName).toPath()), "utf8");
        String regEx = "<\\s*" + tag + "[^<>]*?\\s" + attribute + "\\s*=\\s*(\".*?\"|\'.*?\')";
        Matcher m = Pattern.compile(regEx).matcher(xml);
        if(m.find()) {
            String atr = m.group(1);
            return atr.substring(1, atr.length()-1);
        } else return null;
    } catch(Exception e) {
        return null;
    }
}

Diese Methode liefert dir das gesuchte Attribut als String zurück.
tag und attribute sind dabei der Name des Tags bzw. Attributes.

.*? bedeutet: beliebig viele Zeichen.
Das ? heisst: so wenig Zeichen wie möglich, das ist notwendig, weil =," und ' ja auch beliebige Zeichen sind und versehentlich übersprungen werden könnten.
[^<>] bedeutet: jedes beliebige Zeichen ausser < oder >
\\s ist ein Leerzeichen, Tab oder Zeilenumbruch
| bedeutet oder
(...) ist eine Capture Gruppe

edit: Mein regulärer Ausdruck war nicht ganz in Ordnung. Hab den Code daher noch mal verändert.
 
Zuletzt bearbeitet:

rme

Top Contributor
Naja, der "kennt" XML und merkt sich, ob er gerade in einem Kommentar ist. Er geht das Dokument durch und ruft bei jedem Element die Methode startElement auf. Die Methode bekommt die Attribute als Parameter, sodass du da direkt prüfen kannst, ob ein Attribut "name" enthalten ist.

Möchtest du ein richtiges Code-Beispiel für diese Aufgabe oder erstmal selbst probieren?
 

blurry333

Mitglied
Der SAXparser ist schön und gut, aber wenn ich die Attribute eines tags will, dann muss ich das mit einem INdex aufrufen. Was aber wenn das Attribut mal statt index 0 an index 1 steht.

String tmp = atts.getValue(0); // jetzt bekomm ich den Wert meines 1. Attributs
 
Zuletzt bearbeitet:

rme

Top Contributor
Der Index ist dazu da, dass du dir mit getLength() die Anzahl der Attribute holst und dann dadurch mit einer Schleife iteriest, also getValue und getLocalName auf jeden Index aufrufst. Du darfst nicht annehmen, dass der index als Zahl gesehen irgendeine Bedeutung hat, die mit dem Dokument zu tun hat - nur für eine Schleife verwenden.

Wenn der Name des Attributes bekannt ist, kannst du aber direkt so prüfen, ob es vorhanden ist:
Java:
atts.getValue("attribut") != null
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
K Inhalte Parsen von Website Allgemeine Java-Themen 15
W JSON parsen eines ,mit JS.stringify erstellten Strings Allgemeine Java-Themen 27
C Parsen einer sich updatenden Html mithilfe von jsoup Allgemeine Java-Themen 4
O JSON in Integer parsen Allgemeine Java-Themen 5
S Ini Text aus String parsen Allgemeine Java-Themen 1
OnDemand Datenbankdatei parsen Allgemeine Java-Themen 2
N svg(xml) parsen und manipulieren? Allgemeine Java-Themen 3
OnDemand CSV parsen mehrere Zeilen Allgemeine Java-Themen 22
2 mehrere Json Werte Parsen Allgemeine Java-Themen 3
G JSON parsen Allgemeine Java-Themen 3
W String Parsen und auf eigenes Muster anwenden (kein Regex) Allgemeine Java-Themen 11
looparda Datei parsen Allgemeine Java-Themen 1
T Jsoup: Mehrere Links nacheinander parsen Allgemeine Java-Themen 11
C Benutzereingabe von EXCEL-Funktionen parsen Allgemeine Java-Themen 4
B Such-String parsen mit Klammern Allgemeine Java-Themen 2
L Windows CMD werte Parsen. Allgemeine Java-Themen 2
H Bestimmten Wert aus String parsen Allgemeine Java-Themen 7
0 Parsen Allgemeine Java-Themen 7
W Best Practice Dateien parsen Allgemeine Java-Themen 3
X Tags "parsen" Allgemeine Java-Themen 8
A Parsen mit java_cup - Shift/Reduce Problem Allgemeine Java-Themen 12
C Roboter, Befehle parsen Allgemeine Java-Themen 12
M Informationen aus komplexen String parsen Allgemeine Java-Themen 13
W Dateinamen dynamisch Parsen Allgemeine Java-Themen 12
F JavaMail - Lokale eMail-Datei einlesen und parsen? Allgemeine Java-Themen 9
T String in Date parsen (*ohne* bekanntes Format) Allgemeine Java-Themen 8
M Dateien mit Quelltext parsen Allgemeine Java-Themen 7
W RegEx Zeile parsen Medium Allgemeine Java-Themen 8
S Dateiname mit Regex parsen Allgemeine Java-Themen 3
K _alle_ Sonderzeichen parsen Allgemeine Java-Themen 2
S Feher beim Parsen eines Datums Allgemeine Java-Themen 4
E Reguläre Txt in Tree parsen Allgemeine Java-Themen 2
S Strings zu Color-Instanzen parsen? Allgemeine Java-Themen 7
S Überprüfung/Parsen eines Byte-Arrays Allgemeine Java-Themen 9
martin82 Java-Code aus Text-Datei parsen Allgemeine Java-Themen 3
A String zu Datum parsen - SimpleDateFormat Problem Allgemeine Java-Themen 8
A Datum parsen Allgemeine Java-Themen 9
G Parsen von: if(a > 15 AND (b == 3 OR c != 4)) Allgemeine Java-Themen 3
G String nach Float parsen Allgemeine Java-Themen 2
P OutOfMemoryError beim XML erstellen bzw parsen, mehr RAM? Allgemeine Java-Themen 4
H2SO3- Exception beim date parsen des Jahres 00 Allgemeine Java-Themen 6
H2SO3- date mit pm and am parsen Allgemeine Java-Themen 3
Z Datum ohne Format-Kenntnisse parsen Allgemeine Java-Themen 5
T Wie kontinuierlichen asci input parsen? Allgemeine Java-Themen 3
C Java Quellcode parsen Allgemeine Java-Themen 8
alexpetri Date Parsen Allgemeine Java-Themen 3
G String parsen und Problem mit escaped zeichen Allgemeine Java-Themen 4
M Html parsen Allgemeine Java-Themen 2
D Parameter parsen? Allgemeine Java-Themen 15
V Datum parsen Allgemeine Java-Themen 6
MQue String parsen Allgemeine Java-Themen 11
M wie sinnvoll parsen ? Allgemeine Java-Themen 4
M Link parsen bzw. zerlegen Allgemeine Java-Themen 9
padde479 String in double parsen Allgemeine Java-Themen 6
W Package via Reflection parsen Allgemeine Java-Themen 4
M MP3 Datei selber parsen/werte auslesen Allgemeine Java-Themen 13
J parsen von verschiedenen dokument typen Allgemeine Java-Themen 3
B textzeile parsen Allgemeine Java-Themen 6
T Schlüsseldatei mit Umlauten parsen, aber wie. Allgemeine Java-Themen 6
G mail body parsen (->attachment & filename) Allgemeine Java-Themen 2
J DirectPlay Server-Antwort parsen Allgemeine Java-Themen 2
S String parsen Allgemeine Java-Themen 15
V LogFile parsen Allgemeine Java-Themen 5
E Field-Objekt in JTextField parsen Allgemeine Java-Themen 3
L Prozesse parsen ? Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben