【问题标题】:Validating XML against schema - cannot find declaration of element针对模式验证 XML - 找不到元素的声明
【发布时间】:2017-04-10 13:09:37
【问题描述】:

我对 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 中,所以我不明白这个异常的来源是什么。如果有人能解释验证应该如何工作,我会很高兴。

编辑:我的验证代码:

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>

【问题讨论】:

    标签: java xml validation xsd


    【解决方案1】:

    让您的文档构建器“namespaceAware”应该修复它!

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

    您也可以直接对 Source 对象进行操作,这样代码会更短一些,而且速度可能更快并且使用更少的内存。

    两种变体的示例

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

    【讨论】:

    • 谢谢。像魅力一样工作。
    • 另外请注意,使用 StreamSource 不仅可以缩短代码,而且还可能更快并且使用更少的内存。
    【解决方案2】:

    你没有向我们展示架构,所以我们只能猜测出了什么问题,但我的猜测是元素在错误的命名空间中声明。

    如果这是一个错误的猜测,那么下次你问一个问题时要记住,当人们不向你展示代码时,很难在代码中找到错误。

    【讨论】:

    • 我的问题中引用了该架构。我只是没有包含代码,因为它很长。你可以在这里找到它:tincanapi.com/wp-content/assets/tincan.xsd
    • xml文件中引用了架构&lt;tincan xmlns="http://projecttincan.com/tincan.xsd"&gt;
    • 问题应该是独立的,所以(a)当有类似问题的人在几年后来到这里时,它们仍然有意义,并且(b)让我们这些警惕跟随的人陌生人提供的链接不必冒险。
    • 这并没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review
    • @sidgate 鉴于帖子中提供的信息非常有限,这是对答案的合理猜测。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多