【问题标题】:JAXB 2.0 Validation not workingJAXB 2.0 验证不起作用
【发布时间】:2011-05-22 22:11:31
【问题描述】:

我正在开发 JAXB 2.0,目前正在验证验证部分,因为它没有按预期工作。 下面是验证码

public void validateXMLToSchema(Unmarshaller ummarshaller,String xsdFileName) throws SAXException, JAXBException{
    System.out.println(getClass().getResource(DEFAULT_XSD_NAME).toString());
    Schema schema;
    SchemaFactory schemaFactory=SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    if(null==xsdFileName)
        schema=schemaFactory.newSchema(getClass().getResource(DEFAULT_XSD_NAME));

    else
        schema=schemaFactory.newSchema(new File(xsdFileName));

    ummarshaller.setSchema(schema);
    ummarshaller.setEventHandler( new ValidationEventHandler() {

        @Override
        public boolean handleEvent(ValidationEvent validationevent) {
            if(validationevent.getSeverity()==ValidationEvent.FATAL_ERROR || validationevent.getSeverity()==ValidationEvent.ERROR || validationevent.getSeverity()==ValidationEvent.WARNING){
                ValidationEventLocator  locator = validationevent.getLocator();
                log.info("Line:Col[" + locator.getLineNumber()
                        + ":" + locator.getColumnNumber()
                        + "]:" + validationevent.getMessage());
            }
            return true;
        }
    });

}

这是对方法的调用

Destination destination=new Destination();
    try {
         destination=(Destination)unmarshal(Destination.class,new FileInputStream(new File("C:/Users/Raisonne/Desktop/jaxb/jaxb-ri-20101119/bin/destination.xml")));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (JAXBException e) {
        e.printStackTrace();
    }
    System.out.println(destination.getName());

}

public static <T> T unmarshal( Class<T> docClass, InputStream inputStream )
throws JAXBException, SAXException {
String packageName = docClass.getPackage().getName();
JAXBContext jc = JAXBContext.newInstance( packageName );
Unmarshaller u = jc.createUnmarshaller();
XMLValidator xmlValidator=new XMLValidator();
xmlValidator.validateXMLToSchema(u, null);

根据 XSD,我的必填字段很少,但即使删除它们,它也会给我错误,而它没有给出任何内容并将我的 xml 文件解析到相应的对象 有什么问题吗?

这是XSD的部分

    <xs:element name="destination" type="Destination"/>
  <xs:complexType name="Destination">
    <xs:sequence>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="destinationID" type="xs:string" minOccurs="0"/>
      <xs:element name="shortDescription" type="xs:string" minOccurs="0"/>
      <xs:element name="longDescription" type="xs:string" minOccurs="0"/>
      <xs:element name="stateID" type="xs:string"/>
      <xs:element name="typeCode" type="xs:int"/>
      <xs:element name="countryCode" type="xs:string"/>
      <xs:element name="categories" type="xs:string"/>
      <xs:element name="transport" type="Transport" minOccurs="0" maxOccurs="1"/>
      <xs:element name="culture" type="Culture" minOccurs="0" maxOccurs="1"/>
      <xs:element name="events" type="Events" minOccurs="0" maxOccurs="1"/>
      <xs:element name="placesToVisit" type="PlacesToVisit" minOccurs="0" maxOccurs="1"/>
      <xs:element name="contacts" type="Contact" minOccurs="0" maxOccurs="1"/>
      <xs:element name="addresses" type="address" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

以及生成的Java文件

@XmlElement(required = true)
protected String name;
protected String destinationID;
protected String shortDescription;
protected String longDescription;
@XmlElement(required = true)
protected String stateID;

我正在从 xml 文件中删除 stateID,但验证部分仍然没有警报

提前致谢

【问题讨论】:

  • 提供对应的schema和JAXB对象。
  • 创建了很多对象你只想要根对象吗?

标签: java xml validation jaxb jaxb2


【解决方案1】:

根据这一行

xmlValidator.validateXMLToSchema(u, null);

您没有将 XSD 文件名提供给 XmlValidator。应该是这样的

xmlValidator.validateXMLToSchema(u, "/opt/projects/myschema.xsd");

编辑:嗯,这就是我设法做到的方式,并且运行良好:

void validate(MyRequest requestParameters) throws IllegalArgumentException,MalformedURLException,SAXException {
    try {
        JAXBContext context = JAXBContext.newInstance(MyRequest.class.getPackage().getName());
        Marshaller marshaller = context.createMarshaller();
        marshaller.setSchema(getSchema());
        JAXBElement<MyRequest> rootElement = new JAXBElement<SearchCustomersRequest>(new QName("http://mysite.com/xsd/myproject/", "MyRequest"),
                        MyRequest.class, requestParameters);
        marshaller.marshal(rootElement, new DefaultHandler());
        log.debug("Validation successful");
    } catch (JAXBException e) {
        throw new IllegalArgumentException("Invalid request parameters: " + e.toString(), e);
    }
}

private Schema getSchema() throws MalformedURLException, SAXException {
    if (schema == null) {
        SchemaFactory factory = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
        URL schemaUrl = new URL("http://mysite.com/xsd/myproject/schema-1.0.xsd");
        schema = factory.newSchema(schemaUrl);
    }
    return schema;
}

【讨论】:

  • 我已经在我的 validateXMLToSchema 方法中处理它,如果这是 null 可以看看我帖子中的代码
  • 可能是命名空间问题,我解决了创建具有已定义 QName("mysite.com/xsd/myproject/"..) 的 JAXBElement 的问题
【解决方案2】:

您的代码片段有点难以理解,是否真的发生了解组?您可能需要在 unmarshal 方法中添加最后一行:

public static <T> T unmarshal( Class<T> docClass, InputStream inputStream ) throws JAXBException, SAXException {
    String packageName = docClass.getPackage().getName();
    JAXBContext jc = JAXBContext.newInstance( packageName );
    Unmarshaller u = jc.createUnmarshaller();
    XMLValidator xmlValidator=new XMLValidator();
    xmlValidator.validateXMLToSchema(u, null);
    u.unmarshal(inputStream);
}

【讨论】:

  • 我无法接受您的建议,可能是我的想法无法正常工作:)..您能解释一下..因为我在测试代码中写了同样的东西并且它工作正常,这意味着我我犯了一些根本性的错误
  • 当然,我似乎无法找到您在 Unmarshaller 上调用 unmarshal 的位置。我认为您可能缺少“u.unmarshal(inputStream);”这一行在你的解组方法中。由于从未调用 unmarshal(在 Unmarshaller 上),因此不会发生验证事件。
  • 在上面看到我更新的答案..真的很抱歉,因为你所说的我仍然无法正确得到它,如果可能的话可以用一个小代码片段来解释,这样我就可以接受它..但老实说,这次我要求更多,希望你不会介意
  • 最后出现了有趣的问题,日志语句 log.info("Line:Col[" + locator.getLineNumber() + ":" + locator.getColumnNumber() + "]: " + 验证事件.getMessage());当我将其更改为 system.out.println 时它不起作用:) 感谢它为我节省了一天的帮助,我现在终于可以睡觉了...
【解决方案3】:

当我把我的代码改成这个时真的很奇怪

public class UnMarshallXML {

/**
 * @param args
 * @throws SAXException 
 */
public static void main(String[] args) throws SAXException {
    Destination destination=new Destination();
    try {
         destination=(Destination)unmarshal(Destination.class,new FileInputStream(new File("C:/Users/Raisonne/Desktop/jaxb/jaxb-ri-20101119/bin/destination.xml")));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (JAXBException e) {
        e.printStackTrace();
    }
    System.out.println(destination.getName());

}

public static <T> T unmarshal( Class<T> docClass, InputStream inputStream )
throws JAXBException, SAXException {
String packageName = docClass.getPackage().getName();
System.out.println(packageName);
JAXBContext jc = JAXBContext.newInstance( packageName );
Unmarshaller u = jc.createUnmarshaller();
SchemaFactory schemaFactory=SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema=schemaFactory.newSchema(new File("C:/Users/Raisonne/Desktop/jaxb/jaxb-ri-20101119/bin/destination.xsd"));

u.setSchema(schema);
u.setEventHandler(
        new ValidationEventHandler() {
            // allow unmarshalling to continue even if there are errors
            public boolean handleEvent(ValidationEvent ve) {
                // ignore warnings
                if (ve.getSeverity() != ValidationEvent.WARNING) {
                    ValidationEventLocator vel = ve.getLocator();
                    System.out.println(
                            "Line:Col[" + vel.getLineNumber()
                            + ":" + vel.getColumnNumber()
                            + "]:" + ve.getMessage());
                }

                return true;
            }
        });
// XMLValidator xmlValidator=new XMLValidator();
//xmlValidator.validateXMLToSchema(u, null,inputStream);
@SuppressWarnings("unchecked")
JAXBElement<T> doc = (JAXBElement<T>)u.unmarshal( inputStream );
return doc.getValue();

}

}

一切都开始像魅力一样运作..

【讨论】:

  • 就像我在回答 (stackoverflow.com/questions/4399585/…) 中提到的那样,您添加了实际的 unmarshaller.unmarshal 调用(代码中的倒数第二行)。这会导致 XML 被处理并因此得到验证。
  • 我在我的验证方法上做了同样的事情,但在那种情况下它没有解决,这就是为什么我想知道我只是从我的验证方法中复制代码并将它放在这个里面..
猜你喜欢
  • 2011-05-23
  • 2011-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多