views:

4434

answers:

8

I'm generating xml files that need to conform to an xsd that was given to me. What's the best way to do this?

+8  A: 

You will be wanting Xerces2. A tutorial for this, here (req. signup).

Also, blatently copied from here:

import org.apache.xerces.parsers.DOMParser;
import java.io.File;
import org.w3c.dom.Document;

public class SchemaTest 
{
  public static void main (String args[]) 
  {
      File docFile = new File("memory.xml");
      try
      {
           DOMParser parser = new DOMParser();
           parser.setFeature("http://xml.org/sax/features/validation", true);
           parser.setProperty(
             "http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation", 
                        "memory.xsd");
           ErrorChecker errors = new ErrorChecker();
           parser.setErrorHandler(errors);
           parser.parse("memory.xml");
     }
     catch (Exception e) 
     {
         System.out.print("Problem parsing the file.");
     }
  }
}
SCdF
The SAX parser would be more efficient - the DOM parser creates DOM objects; wasteful operations in this instance.
McDowell
A: 

Are you looking for a tool or a library?

As far as libraries goes, pretty much the de-facto standard is Xerces2 which has both C++ and Java versions.

Be fore warned though, it is a heavy weight solution. But then again, validating XML against XSD files is a rather heavy weight problem.

As for a tool to do this for you, XMLFox seems to be a decent freeware solution, but not having used it personally I can't say for sure.

Adam
+15  A: 

The Java runtime library supports validation. Last time I checked this was the Apache Xerces parser under the covers. You should probably use a javax.xml.validation.Validator.

import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
...

URL schemaFile = new URL("http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd");
Source xmlFile = new StreamSource(new File("web.xml"));
SchemaFactory schemaFactory = SchemaFactory
    .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(schemaFile);
Validator validator = schema.newValidator();
try {
  validator.validate(xmlFile);
  System.out.println(xmlFile.getSystemId() + " is valid");
} catch (SAXException e) {
  System.out.println(xmlFile.getSystemId() + " is NOT valid");
  System.out.println("Reason: " + e.getLocalizedMessage());
}

The schema factory constant is the string http://www.w3.org/2001/XMLSchema which defines XSDs. The above code validates a WAR deployment descriptor against the URL http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd but you could just as easily validate against a local file.

You should not use the DOMParser to validate a document (unless your goal is to create a document object model anyway). This will start creating DOM objects as it parses the document - wasteful if you aren't going to use them.

McDowell
Hours upon the net trying to find this; why haven't I learned to search SO first yet?
Xiong Chiamiov
A: 

I had to validate an XML against XSD just one time, so I tried XMLFox. I found it to be very confusing and weird. The help instructions didn't seem to match the interface.

I ended up using LiquidXML Studio 2008 (v6) which was much easier to use and more immediately familiar (the UI is very similar to Visual Basic 2008 Express, which I use frequently). The drawback: the validation capability is not in the free version, so I had to use the 30 day trial.

KnomDeGuerre
A: 

If you are generating XML files programatically, you may want to look at the XMLBeans library. Using a command line tool, XMLBeans will automatically generate and package up a set of Java objects based on an XSD. You can then use these objects to build an XML document based on this schema.

It has built-in support for schema validation, and can convert Java objects to an XML document and vice-versa.

Castor and JAXB are other Java libraries that serve a similar purpose to XMLBeans.

Todd
A: 

One more answer: since you said you need to validate files you are generating (writing), you might want to validate content while you are writing, instead of first writing, then reading back for validation. You can probably do that with JDK API for Xml validation, if you use SAX-based writer: if so, just link in validator by calling 'Validator.validate(source, result)', where source comes from your writer, and result is where output needs to go.

Alternatively if you use Stax for writing content (or a library that uses or can use stax), Woodstox http://woodstox.codehaus.org can also directly support validation when using XMLStreamWriter. Here's a blog entry showing how that is done:

StaxMan
Hey StaxMan, are there any XMLStreamWriters that do pretty-print indenting? I was surprised that it's not in the standard implementation. Also, is it getting much use? I think it's the right way to go, but there seems very little interest in it.
13ren
just found your post here about StaxMate (but it's not an XMLStreamWriter): http://stackoverflow.com/questions/290326/stax-xml-formatting-in-java/485126#485126
13ren
Yeah, StaxMate can do that. It uses XMLStreamWriter internally for writing content, so you can hook up validator that way too.
StaxMan
A: 
xmllint --schema phone.xsd phone.xml

It's a fast command-line tool, but not in Java: Libxml

13ren
+1  A: 

I found this site to be helpful, too.

http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi.html

It's the one that actually worked for me with a minimum of fuss.