java - How to read objects (Polymorphic) of the chosen class, from the XML using JAX-B -
i created list of polymorphic objects. can convert them xml , vice versa (marshall , unmarshal using jaxb.) read objects chosen class.
i used few tutorials converting object lists jaxb, example one: http://memorynotfound.com/convert-xml-to-polymorphic-object-using-jax-b/ or one: http://bdoughan.blogspot.com/2010/11/jaxb-and-inheritance-using-substitution.html have got animal list, , 2 classes extends abstract animal class, dog, cat , bird. saved list(containing dogs , cats) xml, , xml file cats. possible make?
using code tutorial -> http://memorynotfound.com/convert-xml-to-polymorphic-object-using-jax-b/
jaxbcontext jaxbcontext = jaxbcontext.newinstance(root.class); unmarshaller unmarshaller = jaxbcontext.createunmarshaller(); root root = (root)unmarshaller.unmarshal(new stringreader(xml)); i ouptut:
root{animals=[com.memorynotfound.xml.jaxb.dog@520a3426, com.memorynotfound.xml.jaxb.cat@18eed359,com.memorynotfound.xml.jaxb.bird@643bd123]}
what try achieve is:
root{animals=[ com.memorynotfound.xml.jaxb.cat@18eed359]}
in 1 of answers got idea of xmlevent. fine idea, every tutorial says filtering. want achieve rid of other classes. tried change code:
public xmlevent nextevent() throws xmlstreamexception { // read next event xmlevent e = super.nextevent(); // if it's start element dog if (e.geteventtype() == xmlevent.start_element && ("cat".equals(e.asstartelement().getname().getlocalpart()) || "bird".equals(e.asstartelement().getname().getlocalpart())) ) { // run through events until closing dog event { e = super.nextevent(); } while (e.geteventtype() != xmlevent.end_element || ! ("cat".equals(e.asstartelement().getname().getlocalpart()) || "bird".equals(e.asstartelement().getname().getlocalpart())) ); // read next event after ends e = super.nextevent(); } return e; } but not working, not sure if understand solution.
you can create custom javax.xml.stream.xmleventreader , filter events. here silly - working - example:
public final class filteredxmleventreader extends eventreaderdelegate { final set<string> filteredelements; filteredxmleventreader(xmleventreader delegate, string... filteredelements) { super(delegate); this.filteredelements = new hashset<string>(arrays.aslist(filteredelements)); } public xmlevent nextevent() throws xmlstreamexception { // read next event xmlevent e = super.nextevent(); // if it's start element filtered if (e.geteventtype() == xmlevent.start_element && filteredelements.contains(e.asstartelement().getname().getlocalpart())) { string element = e.asstartelement().getname().getlocalpart(); // run through events until closing similar element { e = super.nextevent(); } while (e.geteventtype() != xmlevent.end_element || !element.equals(e.asendelement().getname().getlocalpart())); // read next tag after closing element e = super.nextevent(); } return e; } } then unmarshall content using xmleventreader:
jaxbcontext jaxbcontext = jaxbcontext.newinstance(root.class); xmleventreader xmlreader = xmlinputfactory.newfactory().createxmleventreader(new stringreader(xml)); unmarshaller unmarshaller = jaxbcontext.createunmarshaller(); root root = (root) unmarshaller.unmarshal(new filteredxmleventreader(xmlreader, "dog", "bird")); then dog , birds elements not read.
note there can issues if multiple filtered elements nested implementation.
edit: edited code above support multiple filtered elements.
Comments
Post a Comment