java - Using JAXB to unmarshal xml with map-like structure to object -


i'm trying unmarshal poorly designed xml object. xml built using generic type element can have number of items name. depending on value of type in something below, include properties different. it's bypassing xsd rulse (yes, has xsd, it's utterly useless).

the xml get:

<something type="actualtype">    <property name="prop1">value1</property>    <property name="prop2">value2</property>    ... </something> 

what should have been:

<actualtype>    <prop1>value1</prop1>    <prop2>value2</prop1> </actualtype> 

how should represented in java:

@xmltype(name="actualtype") public class actualtype {    @xmlelement    public x prop1     @xmlelement    public y prop2  } 

the actual question(s):

is there basic support in jaxb (without external dependencies)? if not, can write custom annotations such able reuse same logic other services using schema?

there couple of ways support use case:

option #1 - jaxb (jsr-222) implementation

if need read xml objects, leverage streamreaderdelegate , following. makes bad xml appear if xml:

import javax.xml.bind.*; import javax.xml.stream.*; import javax.xml.stream.util.streamreaderdelegate; import javax.xml.transform.stream.streamsource;  public class demo {      public static void main(string[] args) throws exception {          xmlinputfactory xif = xmlinputfactory.newfactory();         xmlstreamreader xsr = xif.createxmlstreamreader(new streamsource("src/forum16529016/input.xml"));          xsr = new streamreaderdelegate(xsr) {              @override             public string getlocalname() {                 string localname = super.getlocalname();                 if(!"property".equals(localname) && super.geteventtype() == xmlstreamreader.start_element) {                     return localname;                 }                 if(super.geteventtype() == xmlstreamreader.start_element) {                     return super.getattributevalue(null, "name");                 }                 return localname;             }         };          jaxbcontext jc = jaxbcontext.newinstance(actualtype.class);         unmarshaller unmarshaller = jc.createunmarshaller();         actualtype actualtype = unmarshaller.unmarshal(xsr, actualtype.class).getvalue();         system.out.println(actualtype.prop1);         system.out.println(actualtype.prop2);     } } 

option #2 - eclipselink jaxb (moxy's) @xmlpath extension

note: i'm eclipselink jaxb (moxy) lead , member of jaxb (jsr-222) expert group.

moxy has @xmlpath extension enables map use case.

import javax.xml.bind.annotation.xmltype; import org.eclipse.persistence.oxm.annotations.xmlpath;  @xmltype(name="actualtype") public class actualtype {    @xmlpath("property[@name='prop1']/text())    public x prop1     @xmlpath("property[@name='prop1']/text())    public y prop2  } 

for more information


Comments

Popular posts from this blog

c# - DetailsView in ASP.Net - How to add another column on the side/add a control in each row? -

javascript - firefox memory leak -

Trying to import CSV file to a SQL Server database using asp.net and c# - can't find what I'm missing -