2012-02-01 75 views
1

在xml文档包含模式的情况下,我在使用xml模式验证xml文件时遇到了问题。 xml文件看起来像:如何在xsd里面验证xml?

<?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代码看起来像:

// 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")); 

而且对我来说,问题是如何在这种情况下使用SchemaFactory对象?

我很乐意为您提供帮助!

+0

首先要注意的是:根据模式,您的文档无效。这是因为模式将'book'定义为根元素,而您的文档具有'catalog'作为根元素。所以基本上,您需要将文档分为两部分,架构和内容。有多种方法可以实现这一点;您可以使用XSL转换,或通过DOM API处理文档。 – flyx 2012-02-01 19:59:14

+0

有一个[类似的问题(http://stackoverflow.com/q/8643904/433835)不是很久以前,如果有人想验证对_big ol'_ XML模式架构XML XSD文件架构,参见[我的答案](http://stackoverflow.com/a/8644427/433835)这个,也许它可以帮助。基本上,您需要提供_big ol'_模式以及您的文档模式。这可以通过向SchemaFactory.newSchema(StreamSource [])提供多个模式来完成。 – 2012-02-01 20:05:31

回答

2

我认为这是你想要的;该代码旨在说明,而不是说明良好的编程实践。它已经过您的XML测试。主要假设是文档元素有两个元素,第一个是XSD,第二个是要验证的XML。

如果,例如,您更改44.95至d44.95你会得到这样的输出:

XML是无效的,因为CVC-数据类型-valid.1.2.1: 'd44.95' 不是'float'的有效值。

否则,一切顺利,程序打印XML是有效的。

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()); 
     } 
    } 
} 
+0

就是这样!男人我希望我能评价你的帖子,但没有足够的声誉 – Sergio 2012-02-02 23:26:26

0

作为替代Gardea的解决方案(这是除了我有一个厌恶任何涉及使用DOM罚款),你可以做一个转型中提取的模式和以前一样单独的文件book元素相互验证。我提到这一点,因为验证之前的转换是一种未被充分利用的设计模式。

+0

:)...因此“良好的编程”免责声明;我已经选择了清晰的回应,而且我认为DOM API仍然是最好的教学工具。解释XPath API的用法就是说我有意避免了条件逻辑。感谢您提出这个问题。 – 2012-02-02 13:27:34

+0

@Michael Kay转变之前验证是一个未被充分利用的设计模式 - 完全同意 – Sergio 2012-02-02 23:37:50