我创建了一个多态对象列表。我可以将它们转换为XML,反之亦然(使用JAXB进行编组和解组。)但我想只读取所选类中的对象。
我使用了一些关于通过JAXB转换对象列表的教程,例如: http://memorynotfound.com/convert-xml-to-polymorphic-object-using-jax-b/或此一个:http://bdoughan.blogspot.com/2010/11/jaxb-and-inheritance-using-substitution.html 我有动物清单,还有两个类,它们扩展了抽象动物类,狗,猫和鸟。我将该列表(包含狗和猫)保存到XML,我想从XML文件中只获取Cats。有可能吗?
使用教程中的代码 - > 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));
我会得到ouptut:
Root {animals = [com.memorynotfound.xml.jaxb.Dog@520a3426,com.memorynotfound.xml.jaxb.Cat @ 18eed359,com.memorynotfound.xml.jaxb.Bird @ 643bd123]}
我想要实现的目标是:
Root {animals = [com.memorynotfound.xml.jaxb.Cat@18eed359]}
在其中一个答案中,我了解了XMLEvent。这是一个非常好的想法,但几乎每个教程都说过滤。我想要实现的是摆脱所有其他类。 我试图更改代码:
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;
}
但它没有用,所以我不确定我是否理解这个解决方案。
答案 0 :(得分:1)
因为在Root类中,动物将狗和猫都作为元素,所以如果可用的话,它会尝试将它编组到这两个对象上。
实现目标的一种方法是删除XmlElementWrapper下的一个元素。
vec4 texColor = texture2D(u_texture, v_texCoord) * v_color;
上面会给你:
@XmlElementWrapper(name = "animals")
@XmlElements({
@XmlElement(name = "cat", type = Cat.class)
})
public void setAnimals(List<Animal> animals) {
this.animals = animals;
}
答案 1 :(得分:1)
您可以创建自定义javax.xml.stream.XMLEventReader
并过滤某些事件。这是一个愚蠢的 - 但工作 - 例子:
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 a start element for any filtered
if (e.getEventType() == XMLEvent.START_ELEMENT && filteredElements.contains(e.asStartElement().getName().getLocalPart())) {
String element = e.asStartElement().getName().getLocalPart();
// Then run through events until a closing similar element
do {
e = super.nextEvent();
} while (e.getEventType() != XMLEvent.END_ELEMENT || !element.equals(e.asEndElement().getName().getLocalPart()));
// then read next tag after closing element
e = super.nextEvent();
}
return e;
}
}
然后使用此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"));
然后不会读取Dog
和Birds
元素。
请注意,如果多个已过滤的元素与此实现嵌套,则可能会出现问题。
编辑:编辑上面的代码以支持多个已过滤的元素。