2012-05-23 79 views
7

我试图做的相反JAXB错误:JAXB - Ignore element使非映射的元素

那就是我试图用JAXB解析XML的POJO,我想JAXB如果确实不许失败找到给定元素的匹配Java属性。我知道我可以做架构验证,但我宁愿不这样做。

例子:

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

此XML会失败:

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

因为没有id Java属性

+0

我不知道,如果你能做到这一点使用JAXB。但是,这是XStream的默认行为。 – tibtof

+0

它更多用于单元测试目的。我可能只需要使用XmlUnit,解组XML,然后再重新编制它,并比较过去我所做的。 –

回答

0

我已经能够确认失踪的Java性能的唯一途径(W/o模式)是将XML解组到我的POJO,然后使用相同的POJO将其重新编码为XML并进行比较。

下面是一个使用XMLUnit的示例,它有助于忽略顺序和空白问题。

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

这并不理想,但大多数情况下适用于单元测试。

3

您可以利用ValidationEventHandler来获得您正在查找的行为。意外的元素被视为默认情况下被忽略的警告。为了支持您的使用案例,您可以提供ValdidationEventHandler,该警告无效(请参阅下文)。

演示

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 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(莫西)

我们最近增加了这种行为莫西。您将需要使用EclipseLink 2.4.0或2.3.3。每晚构建可从以下位置获得:


UPDATE

我需要从你的问题捏捏Dog类。以下是我用过的。

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

嗯我试过了,它不起作用(授予它不是MOXY)。我必须再试一次。顺便说一句,我刚刚使用动态XML元素的技巧:http://blog.bdoughan.com/2012/02/xmlanyelement-and-xmladapter.html。当谈到JAXB :) –

+0

我在JDK 1.7.0(对于Mac)中运行了这个确切的代码来获取我发布的异常。您使用的是哪个版本的JDK? –

+0

JDK 1.6我会尽快再试一次。我认为这是因为我正在创造语境。 –