2017-04-10 87 views
1

我對XML驗證非常陌生,所以對於基本問題感到抱歉。我有以下文件:根據模式驗證XML - 無法找到元素聲明

<tincan xmlns="http://projecttincan.com/tincan.xsd"> 
    <activities> 
    <activity id="TestActivity" type="course"> 
     <name lang="und">MyCourse</name> 
     <description lang="und"/> 
     <launch lang="und">start.html</launch> 
    </activity> 
    <activity id="p001" type="objective"> 
     <name lang="und">First Page</name> 
     <description lang="und">First Page</description> 
    </activity> 
    </activities> 
</tincan> 

我想驗證它針對以下模式:http://projecttincan.com/tincan.xsd(我也想從我的XML取出架構和外部提供的話)。

我總是得到以下異常:cvc-elt.1: Cannot find the declaration of element 'tincan'

通過觀察模式,我看到tincan元素被定義那裏,它也存在於我的XML,所以我不udnerstand什麼是源這個例外。如果有人能夠解釋驗證應該如何工作,我會很高興。

編輯:

DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
Document document = parser.parse(stream); 

// 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(getClass().getClassLoader().getResource("tincan.xsd").getFile()); 
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 
validator.validate(new DOMSource(document)); 

EDIT2:模式是鏈接在這裏,但我會在這裏再次發佈它爲清楚:我的驗證代碼

<xs:schema xmlns="http://projecttincan.com/tincan.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tc="http://projecttincan.com/tincan.xsd" targetNamespace="http://projecttincan.com/tincan.xsd" elementFormDefault="qualified"> 
<xs:element name="tincan" type="tincan"></xs:element> 
<xs:complexType name="tincan"> 
<xs:sequence> 
<xs:element name="activities" type="activities" maxOccurs="unbounded"/> 
</xs:sequence> 
</xs:complexType> 
<xs:complexType name="activity"> 
<xs:sequence> 
<xs:element name="name" type="langstring" maxOccurs="unbounded"/> 
<xs:element name="description" type="langstring" maxOccurs="unbounded"/> 
<xs:element name="launch" type="langURI" maxOccurs="unbounded" minOccurs="0"/> 
<xs:element name="resource" type="langURI" maxOccurs="unbounded" minOccurs="0"/> 
<xs:element name="interactionType" type="xs:string" minOccurs="0"/> 
<!-- CMI Interaction fields --> 
<xs:element name="correctResponsePatterns" type="correctResponsePatternList" minOccurs="0"/> 
<xs:element name="choices" type="interactionComponentList" minOccurs="0"/> 
<xs:element name="scale" type="interactionComponentList" minOccurs="0"/> 
<xs:element name="source" type="interactionComponentList" minOccurs="0"/> 
<xs:element name="target" type="interactionComponentList" minOccurs="0"/> 
<xs:element name="steps" type="interactionComponentList" minOccurs="0"/> 
<!-- Extensions --> 
<xs:element name="extensions" type="extensions" minOccurs="0"/> 
</xs:sequence> 
<xs:attribute name="id" type="xs:anyURI"/> 
<xs:attribute name="type" type="xs:string"/> 
</xs:complexType> 
<xs:complexType name="activities"> 
<xs:sequence> 
<xs:sequence> 
<xs:element name="activity" type="activity" maxOccurs="unbounded"/> 
<xs:element name="provider" type="provider" minOccurs="0"/> 
</xs:sequence> 
</xs:sequence> 
</xs:complexType> 
<xs:complexType name="provider"> 
<xs:all> 
<xs:element name="name" type="langstring"/> 
<xs:element name="id" type="xs:string"/> 
<xs:element name="secret" type="xs:string" minOccurs="0"/> 
<xs:element name="public_key" type="xs:string" minOccurs="0"/> 
<xs:element name="info" type="xs:anyURI" minOccurs="0"/> 
</xs:all> 
</xs:complexType> 
<xs:complexType name="correctResponsePatternList"> 
<xs:sequence> 
<xs:element name="correctResponsePattern" type="xs:string" maxOccurs="unbounded"/> 
</xs:sequence> 
</xs:complexType> 
<xs:complexType name="interactionComponentList"> 
<xs:sequence> 
<xs:element name="component" type="interactionComponentType" maxOccurs="unbounded"/> 
</xs:sequence> 
</xs:complexType> 
<xs:complexType name="interactionComponentType"> 
<xs:sequence> 
<xs:element name="id" type="xs:string"/> 
<xs:element name="description" type="langstring" maxOccurs="unbounded"/> 
</xs:sequence> 
</xs:complexType> 
<xs:complexType name="langstring"> 
<xs:simpleContent> 
<xs:extension base="xs:string"> 
<xs:attribute name="lang" type="xs:language"/> 
</xs:extension> 
</xs:simpleContent> 
</xs:complexType> 
<xs:complexType name="extensions"> 
<xs:sequence> 
<xs:element name="extension" type="extension" maxOccurs="unbounded"/> 
</xs:sequence> 
</xs:complexType> 
<xs:complexType name="extension"> 
<xs:simpleContent> 
<xs:extension base="xs:string"> 
<xs:attribute name="key" type="xs:string" use="required"/> 
</xs:extension> 
</xs:simpleContent> 
</xs:complexType> 
<xs:complexType name="langURI"> 
<xs:simpleContent> 
<xs:extension base="xs:anyURI"> 
<xs:attribute name="lang" type="xs:language"/> 
</xs:extension> 
</xs:simpleContent> 
</xs:complexType> 
</xs:schema> 

回答

4

使您的文檔生成器「namespaceAware」應該修復它!

DocumentBuilderFactory f=DocumentBuilderFactory.newInstance();   
    f.setNamespaceAware(true); 

您也可以直接在源對象,這使得代碼有點短上運行,它也可能是速度更快,使用更少的內存。

樣品有兩種變型

package stack43324079; 

import javax.xml.XMLConstants; 
import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.transform.Source; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamSource; 
import javax.xml.validation.Schema; 
import javax.xml.validation.SchemaFactory; 
import javax.xml.validation.Validator; 

import org.junit.Test; 
import org.w3c.dom.Document; 

public class HowToValidateXml { 
    @Test 
    public void validate1() throws Exception { 
     DocumentBuilderFactory f=DocumentBuilderFactory.newInstance(); 
     f.setNamespaceAware(true); 
     DocumentBuilder parser = f.newDocumentBuilder(); 
     Document document = parser.parse(Thread.currentThread().getContextClassLoader().getResourceAsStream("43324079.xml")); 
     SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
     Source schemaFile = new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream("tincan.xsd")); 
     Schema schema = factory.newSchema(schemaFile); 
     Validator validator = schema.newValidator(); 
     validator.validate(new DOMSource(document)); 
    } 

    @Test 
    public void validate2() throws Exception { 
     Source xmlFile = new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream("43324079.xml")); 
     SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
     Schema schema = factory.newSchema(Thread.currentThread().getContextClassLoader().getResource("tincan.xsd")); 
     Validator validator = schema.newValidator(); 
     validator.validate(xmlFile); 
    } 
} 
+0

謝謝。奇蹟般有效。 – Smajl

+1

另請注意,使用StreamSource不僅使代碼更短,而且可能更快,並使用更少的內存。 –

0

你不是我們展示模式,所以我們只能猜測出了什麼問題,但我的猜測是該元素是在錯誤的名稱空間中聲明的。

如果這是一個錯誤的猜測,那麼下次嘗試記住一個問題,那就是當人們沒有向您顯示代碼時,很難在代碼中發現錯誤。

+1

這個架構是在我的問題提及。我只是沒有包含代碼,因爲它很長。你可以在這裏找到它:http://tincanapi.com/wp-content/assets/tincan.xsd – Smajl

+0

模式在xml文件中引用'' – jschnasse

+2

問題應該是自成一體的,因此(a)在幾年後出現類似問題的人時,他們仍然有意義;(b)讓那些對陌生人提供的鏈接保持警惕的人不必冒險。 –

相關問題