gpt4 book ai didi

java - 如何使用 JAX-B 从 XML 读取所选类的对象(多态)

转载 作者:行者123 更新时间:2023-12-02 04:41:06 24 4
gpt4 key购买 nike

我创建了一个多态对象列表。我可以将它们转换为 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 文件中仅获取猫。可以制作吗?

使用教程中的代码 -> 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));

我会得到输出:

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

但它不起作用,所以我不确定我是否理解解决方案。

最佳答案

您可以创建自定义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"));

那么 DogBirds 元素将不会被读取。

请注意,如果此实现嵌套多个过滤元素,则可能会出现问题。

编辑:编辑上面的代码以支持多个过滤元素。

关于java - 如何使用 JAX-B 从 XML 读取所选类的对象(多态),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30171828/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com