JAVA XML parsen und DOM mit Schema validieren

biturbogolf

Grünschnabel
guten morgen
habe ein problem mit dem validieren einer xml gegen eine xsd. laut externen tool und auch eigenem code ist die xml valide.
jetzt wollte ich eine xml in einen DOM parsen und validieren, damit default werte mit in den DOM übernommern werden, aber ich weiß nciht wie ich das genau amchen muss.

kann auch sein, dass ich irgendwelche probleme in der xml oder xsd habe...

bitte um schnelle hilfe

Danke

ich poste einfach mal das was ich habe...


xml:
<?xml version="1.0" encoding="UTF-8"?>
<!--Das ist ein Test-->
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="d:\DOCUME~1\li04096\xmlparsertest\domtestsample\testschema.xsd">
<knoten Date="7.4.2000" Tag="5"/>
<knoten Tag="8"/>
<knoten Jahr="2008" Monat="April" Tag="9">
<kleiner_knoten Name="Sascha"/>
</knoten>
</root>


xsd:
<?xml version="1.0" encoding="UTF-8"?>
<!--W3C Schema erstellt mit XMLSpy v2008 sp1 (http://www.altova.com)-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element ref="knoten" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="knoten">
<xs:complexType>
<xs:sequence>
<xs:element ref="kleiner_knoten" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="Date" type="xs:string" use="optional" default="7.4.2008"/>
<xs:attribute name="Tag" type="xs:short" use="optional" default="5"/>
<xs:attribute name="Jahr" type="xs:short" use="optional" default="2008"/>
<xs:attribute name="Monat" type="xs:string" use="optional" default="April"/>
</xs:complexType>
</xs:element>
<xs:element name="kleiner_knoten">
<xs:complexType>
<xs:attribute name="Name" type="xs:string" use="optional" default="Paul"/>
<xs:attribute name="Nachname" type="xs:string" use="optional" default="Stäglich"/>
</xs:complexType>
</xs:element>
</xs:schema>


javacode:
package dom;

import java.io.File;
import java.io.StringWriter;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSSerializer;

/**
* Simple Sample that:
* - Generates a DOM from scratch.
* - Writes the DOM to a String using an LSSerializer
* @author Jeffrey Rodriguez
* @version $Id: DOMGenerate.java 546623 2007-06-12 20:25:08Z mrglavas $
*/
public class DOMGenerate {
public static void main( String[] argv ) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(true);
DocumentBuilder db = dbf.newDocumentBuilder();

Document doc = db.parse("test.xml");

DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
DOMImplementationLS domImplLS = (DOMImplementationLS)registry.getDOMImplementation("LS");

LSSerializer ser = domImplLS.createLSSerializer(); // Create a serializer for the DOM
LSOutput out = domImplLS.createLSOutput();
StringWriter stringOut = new StringWriter(); // Writer will be a String
out.setCharacterStream(stringOut);
ser.write(doc, out); // Serialize the DOM

System.out.println( "STRXML = "
+ stringOut.toString() );// Spit out the DOM as a String
} catch ( Exception ex ) {
ex.printStackTrace();
}

}
}


Fehlermeldung:
Warning: validation was turned on but an org.xml.sax.ErrorHandler was not
set, which is probably not what is desired. Parser will use a default
ErrorHandler to print the first 10 errors. Please call
the 'setErrorHandler' method to fix this.
Error: URI=file:///D:/Documents%20and%20Settings/li04096/xmlparsertest/domtestsample/test.xml Line=3: Document is invalid: no grammar found.
Error: URI=file:///D:/Documents%20and%20Settings/li04096/xmlparsertest/domtestsample/test.xml Line=3: Document root element "root", must match DOCTYPE root "null".

STRXML = <?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="d:\DOCUME~1\li04096\xmlparsertest\domtestsample\testschema.xsd">
<knoten Date="7.4.2000" Tag="5"/>
<knoten Tag="8"/>
<knoten Jahr="2008" Monat="April" Tag="9">
<kleiner_knoten Name="Sascha"/>
</knoten>
</root><!--Das ist ein Test-->

Das Programm baut einen DOM aus einer xml auf und gibt diesen wieder ordentlich aus, aber ich möche halt die default Werte auch haben...

und die Fehlermeldung stört mich.
 
Uralt und doch auf der ersten Google-Seite ^^

Zumindest für die Grammar-Warnung habe ich bisher eine Lösung gefunden: Eine xsd-Datei erstellt und der DocumentBuilderFactory zugewiesen...

Code:
SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
			Schema schema = schemaFactory.newSchema(Activator.getDefault().getBundle().getEntry("/schema/suite.xsd"));
			dbf = DocumentBuilderFactory.newInstance();
			dbf.setNamespaceAware(true);
			dbf.setValidating(true);
			dbf.setSchema(schema);
			db = dbf.newDocumentBuilder();
			doc = db.newDocument();
			// doc.setStrictErrorChecking(true);
			doc.setXmlStandalone(false);
			doc.setXmlVersion("1.0");

Die anderen Fehler habe ich auch und konnte sie bisher nicht lösen...
 
Hallo,

ich denke ich habe eine Lösung für das Problem gefunden...
Error: URI=file:///D:/Documents%20and%20Settings/li04096/xmlparsertest/domtestsample/test.xml Line=3: Document root element "root", must match DOCTYPE root "null".
... dieser Fehler erscheint, wenn man die DTD Validierung verwendet und keine gültige DTD vorliegt.

dbf.setValidating(true) <- Führt nur DTD Validierung, jedoch keine Schema-Validierung durch.

Schau mal hier:

Beispiele:

membersSchema.xsd:
XML:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	
	<xsd:element name="members">
		<xsd:complexType>
			<xsd:sequence>
				<xsd:element ref="member" maxOccurs="unbounded" />
			</xsd:sequence>
		</xsd:complexType>
	</xsd:element>
	
	<xsd:element name="member">
		<xsd:complexType>
			<xsd:attribute name="name" type="xsd:string" />
			<xsd:attribute name="role" type="xsd:string" use="optional" default="user" />
		</xsd:complexType>
	</xsd:element>
</xsd:schema>

members.xml
XML:
<?xml version="1.0" encoding="UTF-8"?>
<members>
	<member name="user1"/>
	<member name="user2"/>
	<member name="admin" role="admin"/>
</members>

Java:
package de.tutorials;

import java.net.URL;
import java.util.Locale;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.ext.DefaultHandler2;

public class DomParsingWithXmlSchemaValidationExample {
   public static void main(String[] args) throws Exception {

      //error messages in english have a higher google ranking :)  
      Locale.setDefault(Locale.ENGLISH);

      ClassLoader classLoader = DomParsingWithXmlSchemaValidationExample.class.getClassLoader();

      SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
      Schema schema = schemaFactory.newSchema(classLoader.getResource("membersSchema.xsd"));

      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      dbf.setNamespaceAware(true);
      // dbf.setValidating(true); <-- not used here because it performs DTD
      // Validation only!
      dbf.setSchema(schema);

      DocumentBuilder db = dbf.newDocumentBuilder();
      db.setErrorHandler(new DefaultHandler2() {
	 @Override
	 public void error(SAXParseException e) throws SAXException {
	    System.out.println("Error: " + e);
	 }
      });

      Document doc = db.parse(classLoader.getResourceAsStream("members.xml"));

      XPathFactory xpf = XPathFactory.newInstance();
      System.out.println("Implizit per xsd default: " + xpf.newXPath().evaluate("//member[@name='user1']/@role", doc));
      System.out.println("Explizit: " + xpf.newXPath().evaluate("//member[@name='admin']/@role", doc));

   }
}

Ausgabe:
Code:
Implizit per xsd default: user
Explizit: admin

Gruß Tom
 
Zuletzt bearbeitet von einem Moderator:
Zurück