2017-04-10 118 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)让那些对陌生人提供的链接保持警惕的人不必冒险。 –

相关问题