# schema-Validierung mit xerces und jdom: bug in java 1.4?



## jollyroger (8. Sep 2006)

Hallo, 

ich hoffe ihr könnt mir bei folgendem weiterhelfen:

ich nutze:

- java 1.4
- jdom 1.0
- xerces

Damit möchte ich nun eine xml-Datei gegen ein vorhandenes Schema validieren.

Auf der jdom-Seite steht dazu folgendes howto:


```
SAXBuilder builder =
  new SAXBuilder("org.apache.xerces.parsers.SAXParser", true);
builder.setFeature(
  "http://apache.org/xml/features/validation/schema", true);
builder.setProperty(
  "http://apache.org/xml/properties/schema/external-schemaLocation",
  "http://www.w3.org/2001/12/soap-envelope soap-envelope.xsd" + " " +
  "http://kevinj.develop.com/weblog/weblog.xsd weblog.xsd");
Document doc = builder.build(xml);
```

Genau so mache ich es, mein Code-Teil:


```
SAXBuilder saxBuilder = new SAXBuilder("org.apache.xerces.parsers.SAXParser", true);
		
		saxBuilder.setFeature("http://apache.org/xml/features/validation/schema", true);
		
		saxBuilder.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation", "C:\\projects\\rfq.xsd");
		
		try {
			saxBuilder.build(new StringReader(tenderML));
		} catch (JDOMException e) {
			e.printStackTrace();
			System.exit(-1);
		} catch (IOException e) {
			e.printStackTrace();
		}
```

So weit, so gut.......Leider kriege ich bei der Ausführung die Fehlermeldung:




> org.jdom.input.JDOMParseException: Error on line 2: cvc-elt.1: Cannot find the declaration of element 'tender'.



tender ist mein root-Element im xml-Dokument.
Aber die Pfade stimmen, auch die schema-Datei hab ich bei w3c validieren lassen.

ausgiebiges googeln lässt mich nun vermuten das das ein Bug in 1.4 in Bezug auf xerces ist, aber sicher bin ich mir nicht da ich darüber widersprüchliche Informationen gefunden habe.

Deshalb nun meine Frage an euch:

Hat jemand die gleiche Kombination laufen wie ich und validiert damit xml-Dokumente gegen Schemas?

Kennt jemand diesen Bug?

Gibt es Lösungen für dieses Problem?

Vielen Dank im Voraus für alle Antworten........


----------



## byte (8. Sep 2006)

Du musst den Pfad zu Deiner XSD-Datei als URI String angeben. Versuch mal folgendes:


```
saxBuilder.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation", new File("C:/projects/rfq.xsd").toURI().toString());
```


----------



## jollyroger (8. Sep 2006)

Hallo, 

danke für den Tip, aber das hat leider nichts gebracht.

Mein Code sieht jetzt so aus:


```
SAXBuilder saxBuilder = new SAXBuilder("org.apache.xerces.parsers.SAXParser", true);
		
		saxBuilder.setFeature("http://apache.org/xml/features/validation/schema", true);
		
		saxBuilder.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation", new File("C:/projects/rfq.xsd").toURI().toString());
		
		try {
			saxBuilder.build(new StringReader(tenderML));
		} catch (JDOMException e) {
			e.printStackTrace();
			System.exit(-1);
		} catch (IOException e) {
			e.printStackTrace();
		}
```

Der Anfang des xml-files:


```
<?xml version="1.0" encoding="UTF-8"?>
<tender>
   <internal>
      <called_datetime>0002.12.31 -- 12:00:00</called_datetime>
      <insert_datetime>0002.12.31 -- 12:00:00</insert_datetime>
```

Und der Anfang des schema-files:


```
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com"
xmlns="http://www.w3schools.com"
elementFormDefault="qualified">

<xs:element name="tender">
	<xs:complexType>
		<xs:sequence>
		
			

			<xs:element name="internal">
				<xs:complexType>
					<xs:sequence>
						
						<xs:element name="called_datetime" type="xs:dateTime" default="0000-00-00T00:00:00" />
						<xs:element name="insert_datetime" type="xs:dateTime" default="0000-00-00T00:00:00" />
```

Ich krieg leider immer noch den Fehler:


```
org.jdom.input.JDOMParseException: Error on line 2: cvc-elt.1: Cannot find the declaration of element 'tender'.
	at org.jdom.input.SAXBuilder.build(SAXBuilder.java:468)
	at org.jdom.input.SAXBuilder.build(SAXBuilder.java:851)
```


Noch irgendwelche Ideen?


EDIT:

Mir ist gerade noch was aufgefallen:

Ändere ich den Pfad so das er falsch ist, z.b. C:blablub, was es nicht gibt krieg ich immer noch den gleichen Fehler?

Müsste da nicht vorher eine FileNotFoundException kommen?


----------



## Wildcard (8. Sep 2006)

Ich dachte eigentlich der 1.4er Xerces kann gar nicht gegen ein Schema validieren  ???:L


----------



## byte (8. Sep 2006)

Hatte wohl beim ersten Mal was übersehen: Du musst bei diesem Property auch den Namespace mit angeben. Ansonsten musst Du das Property _external-noNamespaceSchemaLocation_ verwenden. Nähere Infos dazu siehe hier.



			
				Wildcard hat gesagt.:
			
		

> Ich dachte eigentlich der 1.4er Xerces kann gar nicht gegen ein Schema validieren  ???:L



Ich glaube, Du verwechselst das mit dem Standard JAXP Parser in 1.4. Der kanns nicht, Xerces aber schon.


----------



## Wildcard (8. Sep 2006)

Stimmt. Bin heute wohl etwas durcheinander  :roll:


----------



## jollyroger (12. Sep 2006)

Hallo, 

erstmal vielen Dank für eure Hilfe...

external-noNamespaceSchemaLocation : 

Damit klappt die Validierung jetzt, mit dem Nachteil das mein dokument keinen Namespace hat, was es aber haben soll.......

Ich verstehe es einfach nicht, warum das nicht klappt, ich fasse nochmal zusammen mit allen Änderungen:


Mein xml-schema, vom w3c-Validator validiert:



```
<?xml version="1.0" encoding="UTF-8"?>
<trcs:schema xmlns:trcs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com"
xmlns="http://www.w3schools.com"
elementFormDefault="qualified">



<trcs:element name="tender">
	<trcs:complexType>
		<trcs:sequence>
		
			

			<trcs:element name="internal">
				<trcs:complexType>
					<trcs:sequence>
						
						<trcs:element name="called_datetime" type="trcs:dateTime" default="0000-00-00T00:00:00" />
						<trcs:element name="insert_datetime" type="trcs:dateTime" default="0000-00-00T00:00:00" />
```

Meine xml-Datei:


```
<?xml version="1.0" encoding="UTF-8"?>
<tender xmlns="trcs">
   <internal>
      <called_datetime>2002-12-31T12:00:00</called_datetime>
      <insert_datetime>2002-12-31T12:00:00</insert_datetime>
```

Hier der java-Code zum Validieren:



```
SAXBuilder saxBuilder = new SAXBuilder("org.apache.xerces.parsers.SAXParser", true);
		
		saxBuilder.setFeature("http://apache.org/xml/features/validation/schema", true);
		
		saxBuilder.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation", 
								new File("C:/projects/trcs/prozesse/tenderml/rfq.xsd").toURI().toString());
				
		try {
			saxBuilder.build(new StringReader(tenderML));
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
```

ergibt den Fehler:


```
org.jdom.input.JDOMParseException: Error on line 2: cvc-elt.1: Cannot find the declaration of element 'tender'.
```

Bin mit meinem Latein am Ende, ich möchte / muss einen Namespace verwenden, und ich sehe einfach keinen Fehler.....

noch irgendwelche Ideen?


----------



## byte (12. Sep 2006)

Wenn Du das Property _external-schemaLocation_ setzen willst, dann musst Du den Target Namespace explizit angeben. Versuch mal folgendes:


```
String schemaURI = new File("C:/projects/trcs/prozesse/tenderml/rfq.xsd").toURI().toString();
String targetNS = "http://www.w3schools.com";

...

saxBuilder.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation", targetNS + " " + schemaURI);
```


----------



## jollyroger (12. Sep 2006)

hallo, 

leider funktioniert das auch nicht...

Der validierende Code sieht nun so aus:


```
String schemaURI = new File("C:/projects/trcs/prozesse/tenderml/rfq.xsd").toURI().toString();
		String targetNS = "http://www.w3schools.com";
		
		SAXBuilder saxBuilder = new SAXBuilder("org.apache.xerces.parsers.SAXParser", true);
		
		saxBuilder.setFeature("http://apache.org/xml/features/validation/schema", true);
		
		saxBuilder.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation", targetNS + " " + schemaURI);
```

Stimmt vielleicht die Namespace-Deklaration im xml-schema nicht?
Der w3c-Validator sagt das es ok ist.........

Hier nochmal die Deklaration, ich möchte "trcs" als namespace haben:



```
<?xml version="1.0" encoding="UTF-8"?>
<trcs:schema xmlns:trcs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com"
xmlns="http://www.w3schools.com"
elementFormDefault="qualified">




<trcs:element name="tender">
	<trcs:complexType>
		<trcs:sequence>
```

Das sieht für mich soweit ok aus....

Im erzeugten xml-Dokument sieht das dann so aus:


```
<?xml version="1.0" encoding="UTF-8"?>
<tender xmlns="trcs">
   <internal>
      <called_datetime>2002-12-31T12:00:00</called_datetime>
```

sieht für mich auch ok aus...

Dummerweise bleibt der Fehler der gleiche.........

Danke für die Hilfe soweit, wäre super wenn du noch einen Tip hast, jetzt hab ich mich solange damit rumgeschlagen, das ich nicht aufgeben möchte........


----------



## Gast (2. Mai 2007)

Versuch dein targetNS so zu ändern:
String targetNS = "http://www.w3schools.com/"; 
es muss unbedingt ein slash am ende sein, sonst wird's nicht funktionieren


----------

