Witam,
Stworzyłem listę polimorficznych obiektów. Mogę konwertować je do XMLa i vice versa (marshalling oraz unmarshaling używając JAXB). Chciałbym jednak odczytywać obiekty tylko wybranej klasy. Przeczytałem kilka tutoriali dotyczących konwersji listy obiektów używając JAXB, np http://memorynotfound.com/convert-xml-to-polymorphic-object-using-jax-b/ czy ten: http://bdoughan.blogspot.com/2010/11/jaxb-and-inheritance-using-substitution.html
Posiadam listę Animal, oraz trzy klasy które rozszerzają abstrakcyjną klase Animal (Dog,Cat, Bird). Zapisuje tą listę i chciałbym odczytać z niej tylko psy. Używam tutorialu -> http://memorynotfound.com/convert-xml-to-polymorphic-object-using-jax-b/
Przykładowy output:
Root{animals=[com.memorynotfound.xml.jaxb.Dog@520a3426, com.memorynotfound.xml.jaxb.Cat@18eed359,com.memorynotfound.xml.jaxb.Bird@22agd431]}
Oczekiwany output: Root{animals=[com.memorynotfound.xml.jaxb.Dog@520a3426]}
Stworzyłem XMLEvent filtr, neistety znalazłem tylko wskazówki jak stworzyć filter na konkretną klasę. Natomiast potrzebuje czegoś co odfiltruje mi wszystkie INNE klasy i zwyczajnie nie mam już pojęcia jak to zrobić.
public final class FilterDogXmlEventReader extends EventReaderDelegate {
FilterDogXmlEventReader(XMLEventReader delegate) {
super(delegate);
}
public XMLEvent nextEvent() throws XMLStreamException {
// Read next event
XMLEvent e = super.nextEvent();
// If it's a start element for dog
if (e.getEventType() == XMLEvent.START_ELEMENT && "Dog".equals(e.asStartElement().getName().getLocalPart())) {
// Then run through events until a closing dog event
do {
e = super.nextEvent();
} while (e.getEventType() != XMLEvent.END_ELEMENT || ! "Dog".equals(e.asEndElement().getName().getLocalPart()));
// then read next event after the dog ends
e = super.nextEvent();
}
return e;
}
}
Tutaj unmarshaluje liste:
JAXBContext jaxbContext = JAXBContext.newInstance(Root.class);
XMLEventReader xmlReader = XMLInputFactory.newFactory().createXMLEventReader(new StringReader(xml));
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Root root = (Root) unmarshaller.unmarshal(new FilterDogXmlEventReader(xmlReader ));
Elementy klasy Dog nie pojawią się w zwróconej liście. Natomiast czy ktoś mógłby doradzic jak zmodyfikować kod by tylko Psy pojawiły się na liście?
Zmiany które wdł mnie powinny działać:
public XMLEvent nextEvent() throws XMLStreamException {
// Read next event
XMLEvent e = super.nextEvent();
// If it's a start element for dog
if (e.getEventType() == XMLEvent.START_ELEMENT && ("Cat".equals(e.asStartElement().getName().getLocalPart()) ||
"Bird".equals(e.asStartElement().getName().getLocalPart()))
)
{
// Then run through events until a closing dog event
do {
e = super.nextEvent();
} while (e.getEventType() != XMLEvent.END_ELEMENT || ! ("Cat".equals(e.asStartElement().getName().getLocalPart()) ||
"Bird".equals(e.asStartElement().getName().getLocalPart()))
);
// then read next event after the ends
e = super.nextEvent();
}
return e;
}
Zwracają błędy. Już naprawde nie mam pomysłu jak to zrobić :(
Mogę oczywiście wypisać błędy, ale wydaje mi się, że po prostu mój tok rozumowania jest zły.