1

I have problems with validating the xml file against xml schema in case when xml document contains schema. The xml file looks like:

<?xml version="1.0"?> <catalog xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:x="urn:book"> <!-- START OF SCHEMA --> <xsd:schema targetNamespace="urn:book"> <xsd:element name="book"> <xsd:complexType> <xsd:sequence> <xsd:element name="author" type="xsd:string"/> <xsd:element name="title" type="xsd:string"/> <xsd:element name="genre" type="xsd:string"/> <xsd:element name="price" type="xsd:float"/> <xsd:element name="publish_date" type="xsd:date"/> <xsd:element name="description" type="xsd:string"/> </xsd:sequence> <xsd:attribute name="id" type="xsd:string"/> </xsd:complexType> </xsd:element> </xsd:schema> <!-- END OF SCHEMA --> <x:book id="bk101"> <author>Gambardella, Matthew</author> <title>XML Developer's Guide</title> <genre>Computer</genre> <price>44.95</price> <publish_date>2000-10-01</publish_date> <description>An in-depth look at creating applications with XML.</description> </x:book> </catalog> 

java code looks like:

// define the type of schema - we use W3C: String schemaLang = "http://www.w3.org/2001/XMLSchema"; // get validation driver: SchemaFactory factory = SchemaFactory.newInstance(schemaLang); // create schema by reading it from an XSD file: Schema schema = factory.newSchema(new StreamSource("...........")); Validator validator = schema.newValidator(); // at last perform validation: validator.validate(new StreamSource("myDoc.xml")); 

And the problem for me is how to use SchemaFactory object in this case ?

I'm greatful for any help!

2
  • First thing to notice: Your document is not valid according to the schema. That's because the schema defines book as the root element, while your document has catalog as root element. So basically, you need to split up your document in its two parts, the schema and the contents. There are multiple ways to achieve this; you might use XSL transformations, or work with the document through the DOM API. Commented Feb 1, 2012 at 19:59
  • There was a similar question not too long ago where someone wanted to validate an XSD file against the big ol' XML Schema schema for XML Schemas—see my answer to this, maybe it can help. Basically, you need to supply the big ol' schema along with your document's schema. This can be done by supplying multiple schemas to the SchemaFactory.newSchema(StreamSource[]). Commented Feb 1, 2012 at 20:05

2 Answers 2

2

I assume this is what you want; the code is meant to illustrate, rather than account for good programming practices. It was tested with your XML. The main assumption is that the document element has two elements, first one the XSD, second the XML to validate.

If, for example, you change 44.95 to d44.95 you will get this output:

XML is not valid because cvc-datatype-valid.1.2.1: 'd44.95' is not a valid value for 'float'.

Otherwise, everything goes fine and the program prints XML is valid.

import java.io.*; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; import javax.xml.validation.*; import org.w3c.dom.NodeList; import org.w3c.dom.Node; import org.xml.sax.SAXException; import javax.xml.xpath.*; import org.xml.sax.InputSource; public class TestValidation { public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException, XPathExpressionException { XPath xpath = XPathFactory.newInstance().newXPath(); NodeList nodes = (NodeList)xpath.evaluate("/*/*", new InputSource("XmlWithEmbeddedXsd.xml"), XPathConstants.NODESET); SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); Validator validator = factory.newSchema(new DOMSource(nodes.item(0))).newValidator(); try { validator.validate(new DOMSource(nodes.item(1))); System.out.println("XML is valid."); } catch (SAXException ex) { System.out.println("XML is not valid because " + ex.getMessage()); } } } 
Sign up to request clarification or add additional context in comments.

Comments

0

As an alternative to Gardea's solution (which is fine except that I have an aversion to anything that involves using the DOM), you could do a transformation to extract the schema and the book element as separate documents before validating one against the other. I mention this because transforming-before-validating is an underused design pattern.

2 Comments

:)... hence the "good programming" disclaimer; I've opted for clarity in the response, and I am arguing that the DOM API is still the best teaching tool. To explain the use of XPath API is to say I intentionally avoided conditional logic. Thank you for bringing this up.
@Michael Kay transforming-before-validating is an underused design pattern - totally agree

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.