2012-05-23 29 views
7

Tôi cố gắng để làm điều ngược lại của: JAXB - Ignore elementHãy lỗi JAXB trên các yếu tố phi ánh xạ

Đó là tôi đang cố gắng để phân tích cú pháp XML với JAXB để một POJO và tôi muốn JAXB thất bại nếu nó KHÔNG tìm thuộc tính Java phù hợp cho một phần tử đã cho. Tôi biết tôi có lẽ có thể làm xác nhận lược đồ nhưng tôi không muốn làm điều đó.

Ví dụ:

@XmlRootElement(name="Dog") 
public class Dog { 
    private String name; 
    public String getName() {return name;} 
    public String setName(String name) {this.name = name}; 
} 

XML này sẽ thất bại:

<Dog> 
<id>blah</id> 
<name>Stuff</name> 
</Dog> 

Vì không có tài sản id Java

+0

Tôi không biết nếu bạn có thể đạt được điều đó bằng jaxb. Tuy nhiên, đây là hành vi mặc định của XStream. – tibtof

+0

Mục đích kiểm tra đơn vị của nó nhiều hơn. Tôi có lẽ sẽ chỉ phải sử dụng XmlUnit, unmarshal XML và sau đó remarshal nó và so sánh đó là những gì tôi đã làm trong quá khứ. –

Trả lời

0

Cách duy nhất tôi đã có thể để xác nhận mất tích tính Java (w/o schema) là để unmarshal XML với POJO của tôi, sau đó remarshal nó vào XML bằng cách sử dụng cùng một POJO và so sánh.

Dưới đây là một ví dụ sử dụng XMLUnit giúp bỏ qua các vấn đề về thứ tự và khoảng trắng.

@Test 
public void testSerialization() throws Exception { 
    XMLUnit.setIgnoreWhitespace(true); 

    EventSearchResults r = 
      JAXB.unmarshal(getClass().getResourceAsStream("/EventSearchResults.xml"), 
        EventSearchResults.class); 
    StringWriter sw = new StringWriter(); 
    JAXB.marshal(r, sw); 
    String expected = 
      IOUtils.toString(getClass().getResourceAsStream("/EventSearchResults.xml"), "UTF-8"); 
    String actual = sw.toString(); 
    //System.out.println(expected); 
    System.out.println(actual); 
    assertXMLEqual(expected, actual); 
} 

Điều này không lý tưởng nhưng đối với hầu hết các phần hoạt động để kiểm tra đơn vị.

3

Bạn có thể tận dụng số ValidationEventHandler để nhận hành vi bạn đang tìm kiếm. Một yếu tố không mong muốn được coi là cảnh báo bị bỏ qua theo mặc định. Để hỗ trợ trường hợp sử dụng của bạn, bạn có thể cung cấp ValdidationEventHandler không thành công trên cảnh báo (xem bên dưới).

Demo

package forum10721257; 

import java.io.File; 
import javax.xml.bind.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Dog.class); 

     File xml = new File("src/forum10721257/input.xml"); 
     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     unmarshaller.setEventHandler(new ValidationEventHandler() { 

      @Override 
      public boolean handleEvent(ValidationEvent event) { 
       return false; 
      } 

     }); 
     Dog dog = (Dog) unmarshaller.unmarshal(xml); 
    } 

} 

JAXB RI Exception

Exception in thread "main" javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"id"). Expected elements are <{}name> 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:647) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:243) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:238) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:105) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.childElement(Loader.java:90) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StructureLoader.childElement(StructureLoader.java:236) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:483) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:465) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:135) 
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:506) 
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:376) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2715) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:607) 
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:116) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:488) 
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:835) 
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764) 
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123) 
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1210) 
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:568) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:202) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:174) 
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157) 
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162) 
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:171) 
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:189) 
    at forum10721257.Demo.main(Demo.java:26) 

EclipseLink JAXB (MOXY)

Chúng tôi vừa mới bổ sung hành vi này để MOXY. Bạn sẽ cần phải sử dụng EclipseLink 2.4.0 hoặc 2.3.3. Một xây dựng hàng đêm có thể thu được từ các vị trí sau:


CẬP NHẬT

tôi cần phải tinh chỉnh các lớp Dog từ câu hỏi của bạn. Dưới đây là những gì tôi đã sử dụng.

Chó

package forum10721257; 

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement(name="Dog") 
public class Dog { 
    private String name; 
    public String getName() {return name;} 
    public void setName(String name) {this.name = name;} 
} 
+1

Hmm Tôi đã thử nó và nó không hoạt động (cấp nó không phải là MOXy).Tôi sẽ phải thử lại lần nữa. BTW Tôi vừa sử dụng mẹo của bạn cho các thành phần XML động: http://blog.bdoughan.com/2012/02/xmlanyelement-and-xmladapter.html. Bạn nhận được xung quanh khi nói đến JAXB :) –

+0

Tôi chạy mã này chính xác trong JDK 1.7.0 (cho Mac) để có được ngoại lệ tôi đăng. Bạn đang sử dụng phiên bản JDK nào? –

+0

JDK 1.6 Tôi sẽ thử lại ngay. Tôi nghĩ đó là vì cách tôi đang tạo ra bối cảnh. –

Các vấn đề liên quan