2012-02-01 71 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