【问题标题】:JAXB - SAXParseException Cannot find the declaration of elementJAXB - SAXParseException 找不到元素的声明
【发布时间】:2013-10-23 04:49:24
【问题描述】:

我在尝试使用给定 xsd 验证对象时遇到问题。 这些类是从 xsd 生成的。

SchemaFactory factory = SchemaFactory
                .newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema(getClass().getResource("/xsd/test.xsd"));
JAXBContext context = JAXBContext.newInstance(aClass);
Unmarshaller u = context.createUnmarshaller();
u.setSchema(schema);
Object anObject = u.unmarshal(new StreamSource(new StringReader(
                MESSAGE)), aClass);

这里是异常信息

[org.xml.sax.SAXParseException: cvc-elt.1: 找不到元素“ACCESREFUSE”的声明。]

这是 XSD:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:include schemaLocation="./include/CJCommon.xsd"/>
 <xs:element name="ACCESREFUSE">
<xs:complexType>
  <xs:sequence maxOccurs="1" minOccurs="1">
    <!-- Entete -->
    <xs:element maxOccurs="1" minOccurs="1" ref="IDOper"/>
    <xs:element maxOccurs="1" minOccurs="1" ref="DateEvt"/>
    <xs:element maxOccurs="1" minOccurs="1" ref="IDEvt"/>
    <xs:element maxOccurs="1" minOccurs="1" ref="IDJoueur"/>
    <xs:element maxOccurs="1" minOccurs="1" ref="HashJoueur"/>
    <xs:element maxOccurs="1" minOccurs="1" ref="IDSession"/>
    <xs:element maxOccurs="1" minOccurs="1" ref="IPJoueur"/>
    <xs:element maxOccurs="1" minOccurs="0" ref="IDCoffre"/>
    <!-- Corps -->
    <xs:element maxOccurs="1" minOccurs="1" ref="TypAg"/>
    <xs:element maxOccurs="1" minOccurs="0" name="CauseRefus" type="string-1024"/>
    <xs:element maxOccurs="1" minOccurs="0" name="TypeRefus">
      <xs:simpleType>
        <xs:restriction base="string-1024">
          <xs:enumeration value="DelaiIdentite"/>
          <xs:enumeration value="RejetIdentite"/>
          <xs:enumeration value="Interdit"/>
          <xs:enumeration value="AutoInterdit"/>
          <xs:enumeration value="OpVerrouille"/>
          <xs:enumeration value="Verrouille"/>
          <xs:enumeration value="Cloture"/>
          <xs:enumeration value="Autre"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:element>
  </xs:sequence>
</xs:complexType>
</xs:element>

元素 ACCESREFUSE 是 xml 的根。

XML:

 <ACCESREFUSE>
      <dateEvt>Tue Oct 15 11:45:48 CEST 2013</dateEvt>
      <hashJoueur>0000000000000000000000000000000000000000</hashJoueur>
      <typAg>JC</typAg>
      <causeRefus>Interdit</causeRefus>
      <typeRefus>Interdiction Temporaire</typeRefus>
      <idjoueur>81.252.190.129</idjoueur>
      <idoper>002</idoper>
      <idsession>301090</idsession>
      <idevt>0</idevt>
      <ipjoueur/>
      <idcoffre/>
 </ACCESREFUSE>

有什么想法吗? 谢谢

【问题讨论】:

    标签: java xml parsing xml-parsing jaxb


    【解决方案1】:

    您可以尝试将您的架构修改为:

    <xs:element name="ACCESREFUSE">
    <xs:complexType name="ACCESREFUSE">
    ...
    </xs:schema>
    

    编辑: 我认为您在加载 XSD 时遇到问题。您能否出于测试目的更改此代码:

    InputStream xmlStream = ...
    Schema schema = factory.newSchema(xmlStream);
    

    请试一试!

    EDIT2:我尝试使用您的 XSD 解析 ACCESREFUSE 类。我不知道你的 ./include/CJCommon.xsd 架构,所以我省略了。这是我的代码:

            SchemaFactory factory = SchemaFactory
                    .newInstance("http://www.w3.org/2001/XMLSchema");
            File file = new File("test.xml");
            Schema schema = factory.newSchema(file);
    
        JAXBContext context = JAXBContext.newInstance(ACCESREFUSE.class);
        Unmarshaller u = context.createUnmarshaller();
        u.setSchema(schema);
        Object anObject = u.unmarshal(new StreamSource(new StringReader(
                getMessage())), ACCESREFUSE.class);
    

    我的 ACCESREFUSE.class:

    @XmlRootElement(name="ACCESREFUSE")
    public class ACCESREFUSE {
    
        protected String v1;
        protected String v2;
        protected String v3;
        protected String v4;
        protected String v5;
        protected String v6;
        protected String v7;
            protected String v8;
        protected String v9;
        protected String CauseRefus;
        protected TypeRefus typeRefus;
    
         public enum TypeRefus{
             DelaiIdentite, RejetIdentite, Interdit, AutoInterdit, OpVerrouille, Verrouille, Cloture, Autre;
        }
    

    消息:

    private static String getMessage() {
    
            return "<ACCESREFUSE>"
                    + "<v1>Tue Oct 15 11:45:48 CEST 2013</v1>"
                    + "<v2>0000000000000000000000000000000000000000</v2>"
                    + "<v3>JC</v3>" + "<v4>Interdit</v4>"   
                    + "<v5>81.252.190.129</v5>"
                    + "<v6>002</v6>" + "<v7>301090</v7>"
                    + "<v8>0</v8>" + "<v9> test </v9>"
                    + "<TypeRefus>RejetIdentite</TypeRefus>"
    
                    + "</ACCESREFUSE>";
        }
    

    并将您的 XSD 修改为简单的字符串元素:

    <?xml version="1.0" encoding="utf-8"?>
    <xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:element name="ACCESREFUSE">
    <xs:complexType>
      <xs:sequence maxOccurs="1" minOccurs="1">
        <!-- Entete -->
        <xs:element maxOccurs="1" minOccurs="1" type="xs:string" name="v1"/>
         ...
    

    程序正常运行! :)

    那么你能检查一下你的./include/CJCommon.xsd 吗? type="xs:string" 是否使用 xs 前缀?

    【讨论】:

    • 嗯,这很奇怪,因为验证在错误之前就有效。只有当一切都很好时,我才会有根元素的错误。我试过 InputStream 但结果是一样的
    • 在异常发生之前,当 XML 不正确时验证工作。例如,它告诉我更改字段...
    • 是的,谢谢。问题出在 CJCommon 中 :) 感谢您的帮助!
    • @BkSouX 所以问题是其中一个包含的 XSD 定义错误?
    【解决方案2】:

    可能是命名空间问题。您应该尝试使用正确的命名空间声明等导入 ./include/CJCommon.xsd。link

    【讨论】:

    • 我无法更改 xsd,但我会尝试。
    猜你喜欢
    • 2016-04-02
    • 1970-01-01
    • 2012-07-02
    • 2012-11-28
    • 2012-09-14
    • 2016-09-09
    • 1970-01-01
    相关资源
    最近更新 更多