# nicht (ganz) valiedes XML einlesen!



## dermoritz (9. Mai 2008)

Guten Tag,

Ich möchte per JDOM/SAXBuilder eine XML Datei einlesen die nicht ganz valide ist. Diese Datei ist das Ausgabe Format eines Programmes (Classification Tree Editor).

Die Invalidität besteht in min. 2 Punkten:

1. der Doctype ist: <!DOCTYPE cteobject SYSTEM "ctexl-1.0.dtd"> und die dtd ist nicht vorhanden

2. es gibt Stellen mit xlink:href="..." oder xlink:type="simple" wobei für xlink der Namesspace fehlt (prefix ... xlink ... is not bound")

Per Editor die Problem zu Lösen (das Sax Parser keine Ausnahem wirft) ist recht einfach: Doctype auf "null" und einen Name space für xlink angeben: xmlns:xlink="http://www.w3.org/1999/xlink".

Mein Frage ist jetzt: Gibt es eine Möglichkeit oder eine Parser der bestimmte XML Fehlr ignorieren kann? Oder könnte ich geschickt die Ausnahemen abfangen und z.b. direkt beim Parsen die entsprechenden Änderungen vornehmen?

Also der Parser soll möglichst unbeeindruckt von Fehlern versuchen einen Baum zu erstellen, Fehler bei Attributen sollten ja zumindest einen einwandfreien Baum ermöglichen.

Die meiner Meinung denkbar schlechteste Variante wäre, die Datei auf eine starre Art und Weise vorzuverarbeiten: "ersetze "ctexl-1.0.dtd" durch "null", lösche jedes vorkommen von "xlink:...."



Nun hätte ich noch ein Frage zu Eclipse (EE) und dessen XML Editor, kann man irgendwie zu einem normalen (XML)Texteditor umschalten? So das man den kompletten Text sieht und nicht nur (abstrahierte) Baumstruktur. Insbesondere Copy/Paste wäre dann einfacher.



Danke im Voraus...


----------



## foobar (9. Mai 2008)

Wenn du die Validierung disabelst, sollte das funktionieren:


```
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
factory.setValidating(false);
```



> Nun hätte ich noch ein Frage zu Eclipse (EE) und dessen XML Editor, kann man irgendwie zu einem normalen (XML)Texteditor umschalten? So das man den kompletten Text sieht und nicht nur (abstrahierte) Baumstruktur. Insbesondere Copy/Paste wäre dann einfacher.


Du kannst unteren Rand des Editors zwischen Design und Code umschalten.


----------



## dermoritz (9. Mai 2008)

"Du kannst unteren Rand des Editors zwischen Design und Code umschalten."

Danke!!

" Wenn du die Validierung disabelst, sollte das funktionieren:"

ich hab es mal probiert, da die validierung aber per default ausgeschaltet ist hatte ich auch wenig hoffnung - es hat nix geholfen.
die beschriebenen fehler scheinen die wohlgeformtheit zu zerstören. die fehlende dtd wirft eine io-file-not-found exception, die anderen eine jdom parseexception.

gibt es eine möglichkeit die exceptions so abzufangen, das der parser die stelle überspringt/löscht und weiter macht? oder gibt es irgendwas, was das erledigt (eventuell auf text/stringbasis?).

ansonsten muss ich das dokument vorher einlesen, die fehlerhaften stellen (von denen ich weiß) entfernen, speichern und dann in den jdom builder schieben?! gibt es da möglichkeiten zur automatisierung? beispiele?
(fange grade an mit java zu programmieren, bin also ein java noob - aber kein programmiernoob ;-))


----------



## byte (9. Mai 2008)

Validierung bedeutet ja nicht Prüfung auf Wohlgeformtheit, sondern die Prüfung gegen eine DTD oder ein XML-Schema.

Grundsätzlich ist es halt so, dass eine Datei nur XML ist, wenn sie wohlgeformt ist. Deswegen setzen XML-Parser auch wohlgeformtes XML voraus. Wenn bei Dir lediglich die Namespace-Deklaration fehlt, dann füg sie doch am Anfang erstmal ein. Danach sollte der Parser ja zufrieden sein.


----------



## dermoritz (9. Mai 2008)

d.h. ich komme nicht drumrum die datei vorzuverarbeiten?

in meinem fall bräuchte ich einen einfachen suchen/ersetzen mechanismus für textdateien oder? gibt es da schon etwas fertiges? bzw. was ist denn eine gute stelle um nach codebeispielen/ fertigen code schnipseln zu suchen?


----------



## foobar (9. Mai 2008)

> in meinem fall bräuchte ich einen einfachen suchen/ersetzen mechanismus für textdateien oder?


Das kannste ganz einfach mit einem Pattern lösen. Such mal nach Regex oder Pattern Matching.


----------



## dermoritz (9. Mai 2008)

danke,

wie ich erwähnt hab bin ich aber java noob, d.h. ich muss erstmal die datei einlesen (da hab ich mir "randomaccessfile" ausgesucht -ok?), die entsprechenden zeilen finden und bearbeiten das mach ich per regexp oder einfach per stringvergleich, und dann dass ganze wieder speichern.

mit glück find ich ein gerüst für alls das und muss nur noch die such muster festlegen.


----------



## byte (9. Mai 2008)

Du musst doch einfach nur im Root-Element den xlink Namespace eintragen. Der Doctype ist wurscht, gehört nicht zur Wohlgeformtheit.


----------



## Guest (9. Mai 2008)

im doctype wird aber auf eine dtd verwiesen "...SYSTEM datei.dtd" und diese stelle wirft eine io exception "file not found".

theoretisch ist mir ja völlig klar was ich machen muss - habs ja schon per hand geändert, dann verschwinden die exceptions. aber praktisch bin ich mir da unsicher, da ich ja eigentlich noch nie was mit java gemacht hab. ich hatte halt gehofft, dass ich um "suchen/ersetzen" herumkomme.


----------



## byte (9. Mai 2008)

Der Doctype wird ignoriert, wenn Du die Validierung ausschaltest.

Du musst also lediglich die Namespace Deklaration dem Root-Element hinzufügen.


----------



## dermoritz (13. Mai 2008)

"Der Doctype wird ignoriert, wenn Du die Validierung ausschaltest. "

die validierung war wie gesagt die ganze zeit aus - und es wurde der fehler geworfen. inzwischen hab ich aber die dtd datei - also der teil der frage ist geklärt.

und das ich den namespace "xmlns:xlink="http://www.w3.org/1999/xlink" hinzufügen muss war mir von anfang an klar, nur eben nicht die vorgehensweise.

wünschenswert wäre das hinzufügen desnamespaces per xml api (z.b. jdom) zu erledigen. geht das? der saxbuilder wirft ja gleich den fehler. funktioniert es mit einem anderen builder?
also kann man eine xml datei (da nicht wohlgeformt ist es eigentlich gar keine?!) per xml api manipulieren ohne sie fehlerwerfend einzulesen?

wie erwähnt der umweg über: datei als textdatei einlesen und string "xmlns:xlink="http://www.w3.org/1999/xlink" einfügen und dann per saxbuilder einzulesen erscheint mir umständlich.


----------



## byte (13. Mai 2008)

Damit eine Textdatei als XML durchgeht, muss sie eine bestimmte Syntax besitzen. Man spricht dann davon, dass die Datei wohlgeformt ist. Für gewöhnlich macht jeder XML-Parser vor dem Parsen eine Prüfung auf Wohlgeformtheit. Schlägt dieser fehl, dann handelt es sich nicht um XML, demnach ist die Datei für den XML-Parser ungültig.

Ich kann Dir nicht sagen, ob es ein Parser gibt, dessen Well-Formed-Check nicht ganz so strikt ist, dass er die fehlende XML-Namespace-Deklaration durchgehen lässt. Du könntest das also entweder mal evaluieren, indem Du verschiedene Parser durchprobierst. Schneller wirst Du aber ans Ziel kommen, indem Du die Deklaration einfach kurz als Text in die Datei schreibst.

Davon abgesehen würde ich dem Verursacher der "beinahe"-XML-Struktur aber mal erzählen, was er da verzapft hat.


----------



## dermoritz (13. Mai 2008)

danke,

der verursacher sagt eigentlich gar nicht, dass es xml ist, es ist das ausgabe format eines programmes (sie erster post).

da ich nun die dtd datei hab, hab ich mal die validierung angeschaltet und gleich einen fehler bzgl. des eingefügten xmlns:xlink bekommen:

Attribute "xmlns:xlink" must be declared for element type "cteobject".

("cteobject" ist das rootelement deklariert im doctype) weiß jemand was das bedeutet? was kann man machen um validität diesbezüglich herzustellen.


----------



## byte (13. Mai 2008)

http://www.w3.org/TR/REC-xml-names/#ns-decl


----------



## dermoritz (13. Mai 2008)

...genau deswegen frag ich mich wieso das:


```
<cteobject xmlns:xlink="http://www.w3.org/1999/xlink">
</cteobject>
```

falsch sein soll. das entspricht doch exakt dem beispiel?!


edit: kann es daran liegen das die deklaration im dtd fehlt? diese namespace angabe hab ich ja nachträglich einfügen müssen. wie fügt man sowas in einem dtd ein?


----------



## Gast (16. Mai 2008)

Wenn ich mich nicht irre dann müsste das hier helfen: 
	
	
	
	





```
<!ATTLIST cteobject xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
```


----------



## Gast (11. Jun 2008)

Hallo,
Ich möchte per C# eine XML Datei einlesen die nicht ganz valide ist. Diese Datei ist das Ausgabe Format eines Programmes (Classification Tree Editor). 

der Doctype ist: <!DOCTYPE cteobject SYSTEM "ctexl-1.0.dtd"> und die dtd ist nicht vorhanden,
Also meine Frage ist wie kann ich die validierung beheben.

vielen Dank im voraus


----------



## binci (18. Jun 2008)

hallo leute ich hab folgendes problem:

ich würde gerne meine daten aus dem User.xml file holen und auslesen können, doch irgendwas stimmt nicht, er erkennt das file nicht?

User.xml:


<Users>
<User id = "James">
        <VName>James</VName>
        <NName>Schuster</NName>
        <Username>James</Username>
        <PWD>abc</PWD>
        <Alter>22</Alter>
        <Universitaet>TU</Universitaet>
        <Land>Oesterreich</Land>

        <Friends>
                <Friend>Binci</Friend>
                <Friend>Goezi</Friend>
                <Friend>Hansi</Friend>
        </Friends>
</User>

<User id = "Hansi">
        <VName>Hans</VName>
        <NName>Schneider</NName>
        <Username>Hansi</Username>
        <PWD>hs</PWD>
        <Alter>18</Alter>
        <Universitaet>TU</Universitaet>
        <Land>Oesterreich</Land>

<Friends>
                <Friend>Tommy</Friend>
                <Friend>Goezi</Friend>
                <Friend>Binci</Friend>
        </Friends>
</User>

der code wo das User.xml verwendet wird schaut so aus:


	 public User getUser(String id){

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse("\\User.xml");

NodeList n0= doc.getElementsById("VName");
NodeList n1= doc.getElementsByTagName("NName");
NodeList n2= doc.getElementsByTagName("Alter");
NodeList n3= doc.getElementsByTagName("Username");
NodeList n4= doc.getElementsByTagName("Universitaet");
NodeList n5= doc.getElementsByTagName("Land");
NodeList n6= doc.getElementsByTagName("Friend");
return new User();

und Fehler bekomm ich folgende:


ShowFriendsTest.java:111: cannot find symbol
symbol  : class DocumentBuilder
location: class data.User
DocumentBuilder db = dbf.newDocumentBuilder();
^
ShowFriendsTest.java:112: cannot find symbol
symbol  : class Document
location: class data.User
Document doc = db.parse("\\User.xml");
^
ShowFriendsTest.java:114: cannot find symbol
symbol  : class NodeList
location: class data.User
NodeList n0= doc.getElementsById("VName");
^
ShowFriendsTest.java:115: cannot find symbol
symbol  : class NodeList
location: class data.User
NodeList n1= doc.getElementsByTagName("NName");
^
ShowFriendsTest.java:116: cannot find symbol
symbol  : class NodeList
location: class data.User
NodeList n2= doc.getElementsByTagName("Alter");
^
ShowFriendsTest.java:117: cannot find symbol
symbol  : class NodeList
location: class data.User
NodeList n3= doc.getElementsByTagName("Username");
^
ShowFriendsTest.java:118: cannot find symbol
symbol  : class NodeList
location: class data.User
NodeList n4= doc.getElementsByTagName("Universitaet");
^
ShowFriendsTest.java:119: cannot find symbol
symbol  : class NodeList
location: class data.User
NodeList n5= doc.getElementsByTagName("Land");
^
ShowFriendsTest.java:120: cannot find symbol
symbol  : class NodeList
location: class data.User
NodeList n6= doc.getElementsByTagName("Friend");
^
9 errors


kann mir jemand helfen?


----------



## Gast (26. Jun 2008)

ich habe es mit dem Code versucht leider bekomme ich den Fehler: Fehler1 Systemliteral-Zeichenfolge wird erwartet.
Bitte um hilfe!


----------



## Gast (26. Jun 2008)

diesem Code:
<!ATTLIST cteobject xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">


----------

