Проверка JAXB 2.0 не работает

Я работаю над 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;

я удалял stateID из файла xml, но в части проверки по-прежнему не было тревоги

заранее спасибо


person Umesh Awasthi    schedule 09.12.2010    source источник
comment
Предоставьте соответствующую схему и объект JAXB.   -  person Teja Kantamneni    schedule 09.12.2010
comment
создано много объектов, вам нужен только корневой объект?   -  person Umesh Awasthi    schedule 09.12.2010


Ответы (3)


Ваш фрагмент кода немного сложен для понимания, действительно ли происходит немаршалирование? Возможно, вам придется добавить последнюю строку в ваш метод 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);
}
person bdoughan    schedule 09.12.2010
comment
я не могу понять, что вы предложили, может быть, мой разум не работает :) .. вы можете немного объяснить .. поскольку я написал то же самое в своем тестовом коде, и он работает нормально, это означает, что я делаю какую-то фундаментальную ошибку - person Umesh Awasthi; 09.12.2010
comment
Конечно, я, кажется, не могу найти, где вы называете немаршалером Unmarshaller. Я думаю, вам может не хватать строки u.unmarshal(inputStream); в вашем немаршальном методе. Поскольку unmarshal (на Unmarshaller) никогда не вызывается, никаких событий проверки не происходит. - person bdoughan; 09.12.2010
comment
см. мой обновленный ответ выше ... и мне очень жаль, поскольку то, что вы сказали, я все еще не могу понять это правильно, если возможно, могу объяснить с помощью небольшого фрагмента кода, так что, может быть, мой разум может это принять ... но, честно говоря, на этот раз я требуя немного больше надежды, что вы не будете возражать - person Umesh Awasthi; 09.12.2010
comment
Наконец, возникла забавная проблема: оператор журнала log.info(Line:Col[ + locator.getLineNumber() + : + locator.getColumnNumber() + ]: + validationevent.getMessage()); это не работало, когда я изменил его на system.out.println, это сработало :) Спасибо за помощь, это спасло мой день, теперь я наконец-то могу спать... - person Umesh Awasthi; 09.12.2010

Согласно этой линии

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;
}
person Timoteo Ponce    schedule 09.12.2010
comment
я обрабатываю это в своем методе validateXMLToSchema, если это значение null, можно посмотреть код в моем сообщении - person Umesh Awasthi; 09.12.2010
comment
Возможно, это проблемы с пространством имен, я решил, что создаю JAXBElement с определенным QName(mysite.com/xsd/myproject /..) - person Timoteo Ponce; 09.12.2010

Действительно странно, когда я изменил свой код на это

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

}

}

все стало работать как шарм..

person Umesh Awasthi    schedule 09.12.2010
comment
Как я уже упоминал в своем ответе (stackoverflow.com/questions/4399585/), вы добавили фактический вызов unmarshaller.unmarshal (вторая последняя строка в вашем коде). Это приводит к тому, что XML обрабатывается и, следовательно, проверяется. - person bdoughan; 09.12.2010
comment
я сделал то же самое с моим методом проверки, но в этом случае это не сработало, поэтому мне интересно, что я просто скопировал код из моего метода проверки и поместил его внутрь этого.. - person Umesh Awasthi; 09.12.2010