# XML Datei mit Schemafehler parsen



## shigoro (10. Feb 2005)

```
InputStream inStream = this.getClass().getClassLoader().getResourceAsStream(FileName);
		
javax.xml.parsers.DocumentBuilder xdb = org.apache.soap.util.xml.XMLParserUtils.getXMLDocBuilder();

doc = xdb.parse(inStream);
```

Wenn ich eine XML Datei in ein DOM-Objekt einlese wie oben, dann funktioniert das grundsätzlich. Wenn die Datei jedoch Fehler im Schema hat, z.B. ungülter Knoten --> <node??/>, dann kommt es zu einem Fehler 



> [Fatal Error] :5:19: Element type "node" must be followed by either attribute specifications, ">" or "/>".



und das Programm wird abgebrochen. Kann ich den Fehler irgendwie abfangen, so dass das Programm danach weiterläuft?

MfG


----------



## Bleiglanz (10. Feb 2005)

Exception mit catch auffangen?

grundsätzlich nein, alle xml parser sind per Spec verpflichtet, nach einem Fehler nicht weiterzumachen, also wirst du keinen "halb vollständigen DOM Tree" erhalten....

Alternative: mit SAX arbeiten (nicht validierend) und Fehler bei einzelnen Elementen mit catch abfangen


----------



## shigoro (10. Feb 2005)

Hmm.. Ok  ???:L 

Kann ich dann irgendwie vor dem Parsen überprüfen ob das XML-Dokument Fehler in der Struktur enthält?


----------



## KSG9|sebastian (10. Feb 2005)

müsste mit sax glaub ich auch gehen..


----------



## shigoro (10. Feb 2005)

KSG9|plak hat gesagt.:
			
		

> müsste mit sax glaub ich auch gehen..



Und wie?  :wink:


----------



## Bleiglanz (10. Feb 2005)

einfach durchparsen?

bringt aber nichts, denn im erfolgsfall müsstest du ja nochmal parsen um den DOM baum zu erhalten???

also lieber mit try-catch das DOM erstellen, wenns scheitert wars even nicht korrekt?


----------



## Roar (10. Feb 2005)

tjo doch es gibt ne möglichkeit weiter zu parsen nach fehlern mit den "parser features" von xerces:


```
// dom:
DOMParser parser = new DOMParser();
try {
parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error" ,
true);
}
catch (SAXException e) {
System.err.println("could not set parser feature");
}

// sax

SAXParser parser = ...;
XMLReader reader = parser.getXMLReader();
try {
reader.setFeature("http://apache.org/xml/features/continue-after-fatal-error" ,
true);
}
catch (SAXException e) {
// fehla
}
```


----------



## dark_red (10. Feb 2005)

Bleiglanz hat gesagt.:
			
		

> grundsätzlich nein, alle xml parser sind per Spec verpflichtet, nach einem Fehler nicht weiterzumachen, also wirst du keinen "halb vollständigen DOM Tree" erhalten....



Ich bin mir nicht ganz sicher, aber ist es nicht so, dass XML Dokumente nur "well-formed" sein müssen, um durch den Parser zu gehen? Der baut halt am Ende einen DOM-Tree auf und wenn der nicht zum Schema passt, dann werden die Exceptions nach dem Parsen beim Zugriff auf den Baum geworfen (bzw wenn der Baum nicht mit dem Schema übereinstimmt)?


----------



## Bleiglanz (10. Feb 2005)

stimmt, bei nicht well-formed abbruch

wenn well-formed, dann hängts davon ab, ob man validating=true für den parser eingestellt hat (natürlich nur, wenns überhaupt eine DTD oder ein Schema gibt)

Die frage nach <node??/> bezog sich aber wohl auf "nicht well formed", und da macht eigentlich kein Parser weiter

aber s.o


----------



## Guest (11. Feb 2005)

Ja sorry... Habs verwechselt  :? 

Ich meinte eigentlich auch "well-formed" und nicht ein Fehler im Schema...


----------



## shigoro (11. Feb 2005)

Anonymous hat gesagt.:
			
		

> Ja sorry... Habs verwechselt  :?
> 
> Ich meinte eigentlich auch "well-formed" und nicht ein Fehler im Schema...



War ich ;-)


----------



## shigoro (11. Feb 2005)

Aber ich verstehs immer noch nicht ganz  :? 


```
boolean wellFormed = true;

InputStream inStream = this.getClass().getClassLoader().getResourceAsStream(templateDeklarationFileName);

if (inStream == null) {
	throw new IOException("Cannot find " + templateDeklarationFileName);
}

javax.xml.parsers.DocumentBuilder xdb = org.apache.soap.util.xml.XMLParserUtils.getXMLDocBuilder();

try {
	doc = xdb.parse(inStream);
} catch (SAXException e) {
	wellFormed = false;
}
```

Also ich lese die Datei wie oben ein und versuche sie dann zu parsen... Nun möchte ich einfach das folgendes passiert:


```
if (wellFormed) {

	//Verschiedene Verarbeitungsschritte...

	bds = new ByteArrayDataSource(in);
}
		
else{
	bds = new ByteArrayDataSource(inStream);
}
		
return new DataHandler(bds);
```

Wie kann ich also machen, dass wenn die Datei nicht "well-formed" ist, dass es keinen Fehler gibt und das Programm nicht beendet wird, sondern einfach "wellFormed" auf false gesetzt wird und dann in der unteren If-Schlause der else-Teil ausgeführt wird??

MfG


----------



## Bleiglanz (11. Feb 2005)

shigoro hat gesagt.:
			
		

> ```
> boolean wellFormed = true;
> try {
> doc = xdb.parse(inStream);
> ...



hä? genau das macht doch dein code???


----------



## shigoro (11. Feb 2005)

Sooo.. Ich habe den Fehler gefunden   

Und zwar lag er hier: 


```
else{
   bds = new ByteArrayDataSource(inStream);
}
```

Ich habe da mal ein Try-Catch drum gepackt und dann kam der Fehler:



> java.lang.RuntimeException: Stream closed



Nun lese ich einfach die Datei nochmals neu in den InputStream ein und es funktioniert:



```
else {
	inStream = this.getClass().getClassLoader().getResourceAsStream(templateDeklarationFileName);
	bds = new ByteArrayDataSource(inStream);
}
```

Aber wieso ist das so? Wird der InputStream automatisch geschlossen nach dem parsen?


----------



## Bleiglanz (11. Feb 2005)

ja, wenn ein strom ausgelesen ist ist er leer....


----------

