根据XSD文件验证XML文件的最佳方法是什么?

我正在生成一些XML文件,需要符合给我的xsd文件。 验证它们符合的最佳方法是什么?

Java运行时库支持验证。 上次我检查了这个是Apache Xerces解析器。 你应该使用一个javax.xml.validation.Validator 。

import javax.xml.XMLConstants; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.*; import java.net.URL; import org.xml.sax.SAXException; //import java.io.File; // if you use File import java.io.IOException; ... URL schemaFile = new URL("http://host:port/filename.xsd"); // webapp example xsd: // URL schemaFile = new URL("http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"); // local file example: // File schemaFile = new File("/location/to/localfile.xsd"); // etc. Source xmlFile = new StreamSource(new File("web.xml")); SchemaFactory schemaFactory = SchemaFactory .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); try { Schema schema = schemaFactory.newSchema(schemaFile); Validator validator = schema.newValidator(); validator.validate(xmlFile); System.out.println(xmlFile.getSystemId() + " is valid"); } catch (SAXException e) { System.out.println(xmlFile.getSystemId() + " is NOT valid reason:" + e); } catch (IOException e) {} 

模式工厂常量是定义XSD的字符串http://www.w3.org/2001/XMLSchema 。 以上代码根据URL http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd验证WAR部署描述符,但是您可以轻松验证本地文件。

您不应使用DOMParser来验证文档(除非您的目标是创建文档对象模型)。 这将开始创建DOM对象,因为它解析文档 – 如果你不打算使用它们是浪费的。

以下是使用Xerces2的方法 。 这是一个教程, 在这里 (请求注册)。

原始出处:从这里公然抄袭:

 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."); } } } 

我们使用ant构建我们的项目,所以我们可以使用schemavalidate任务来检查我们的配置文件:

 <schemavalidate> <fileset dir="${configdir}" includes="**/*.xml" /> </schemavalidate> 

现在顽皮的配置文件将失败我们的构建!

http://ant.apache.org/manual/Tasks/schemavalidate.html

我发现这个网站也是有帮助的。

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

这是真正为我工作的一个小事。

使用Java 7,您可以按照包描述中提供的文档。

 // parse an XML document into a DOM tree DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document document = parser.parse(new File("instance.xml")); // create a SchemaFactory capable of understanding WXS schemas SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); // load a WXS schema, represented by a Schema instance Source schemaFile = new StreamSource(new File("mySchema.xsd")); Schema schema = factory.newSchema(schemaFile); // create a Validator instance, which can be used to validate an instance document Validator validator = schema.newValidator(); // validate the DOM tree try { validator.validate(new DOMSource(document)); } catch (SAXException e) { // instance document is invalid! } 

由于这是一个很受欢迎的问题,我还想指出的是,java可以使用xsi:SchemaLocationxsi:noNamespaceSchemaLocation (或xsi)来验证“引用”xsd,例如,如果.xml文件本身指定了XSD,特定的命名空间)如下所述:

 <document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.example.com/document.xsd"> ... 

或SchemaLocation(总是一个命名空间到xsd映射的列表)

 <document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:SchemaLocation="http://www.example.com/document http://www.example.com/document.xsd"> ... 

“如果你创建了一个没有指定URL,文件或源的模式,那么Java语言就会创建一个在被验证的文档中查找的模式,以找到它应该使用的模式,例如:”

 SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); Schema schema = factory.newSchema(); 

这对于多个命名空间是有效的。这种方法的问题在于xmlsns:xsi可能是一个网络位置,所以它会在每次验证时都会出现并击中网络,而不总是最优的。

下面是一个例子,它根据它引用的任何XSD来验证XML文件(即使它必须从网络中提取它们):

  public static void verifyValidatesInternalXsd(String filename) throws Exception { InputStream xmlStream = new new FileInputStream(filename); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(true); factory.setNamespaceAware(true); factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); DocumentBuilder builder = factory.newDocumentBuilder(); builder.setErrorHandler(new RaiseOnErrorHandler()); builder.parse(new InputSource(xmlStream)); xmlStream.close(); } public static class RaiseOnErrorHandler implements ErrorHandler { public void warning(SAXParseException e) throws SAXException { throw new RuntimeException(e); } public void error(SAXParseException e) throws SAXException { throw new RuntimeException(e); } public void fatalError(SAXParseException e) throws SAXException { throw new RuntimeException(e); } } 

即使xml文件引用了url的链接,通过手动指定xsd(请参阅此处的其他答案)或使用“XML catalog” 样式解析器 ,也可以避免从网络中拉取引用的XSD。 Spring显然也可以拦截 URL请求来服务本地文件进行验证。 或者你可以通过setResourceResolver来设置你自己,例如:

 Source xmlFile = new StreamSource(xmlFileLocation); SchemaFactory schemaFactory = SchemaFactory .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = schemaFactory.newSchema(); Validator validator = schema.newValidator(); validator.setResourceResolver(new LSResourceResolver() { @Override public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) { InputSource is = new InputSource( getClass().getResourceAsStream( "some_local_file_in_the_jar.xsd")); // or lookup by URI, etc... return new Input(is); // for class Input see // https://stackoverflow.com/a/2342859/32453 } }); validator.validate(xmlFile); 

另请参阅这里另一个教程。

还有一个答案:因为你说你需要验证你正在生成的文件(写作),所以你可能想要在写作的时候验证内容,而不是先写,然后回头验证。 如果您使用基于SAX的编写器,那么您可以使用JDK API进行Xml验证:如果是这样,只需通过调用“Validator.validate(source,result)”链接验证器,其源代码来自您的编写器,结果是输出需要去的地方。

或者,如果您使用Stax编写内容(或使用或可以使用stax的库),Woodstox http://woodstox.codehaus.org也可以在使用XMLStreamWriter时直接支持验证。; 这是一个博客条目,显示如何完成:

如果以编程方式生成XML文件,则可能需要查看XMLBeans库。 使用命令行工具,XMLBeans将自动生成并打包一组基于XSD的Java对象。 然后,您可以使用这些对象来构建基于此架构的XML文档。

它内置了对模式验证的支持,可以将Java对象转换为XML文档,反之亦然。

Castor和JAXB是与XMLBeans类似的其他Java库。

如果你有一台Linux机器,你可以使用免费的命令行工具SAXCount。 我发现这非常有用。

 SAXCount -f -s -n my.xml 

它验证对dtd和xsd。 5s为50MB文件。

在debian中,它位于包“libxerces-c-samples”中。

dtd和xsd的定义必须在xml中! 你不能单独配置它们。

你在找工具还是图书馆?

就图书馆而言,几乎事实上的标准是Xerces2 ,它具有C ++和Java版本。

不过要注意,这是一个重量级的解决方案。 但是,再次验证XML对XSD文件是一个相当重的问题。

至于为你做这个工具, XMLFox似乎是一个体面的免费软件解决方案,但没有亲自使用它,我不能肯定地说。

我只需要一次对XSD验证XML,所以我尝试了XMLFox。 我发现它很混乱,很奇怪。 帮助说明似乎不匹配接口。

我最终使用了LiquidXML Studio 2008(v6),它更容易使用,而且更加直接熟悉(UI非常类似于我经常使用的Visual Basic 2008 Express)。 缺点:验证功能不在免费版本,所以我不得不使用30天的试用。