如何解决Stax XMLStreamReader 检查下一个事件而不前进
我有一个包含许多事件的大 XML
文件。我想unmarshal
他们。由于它是一个大文件,我想一个一个地 unmarshal
它们,这样整个文件就不会存储在内存中。它对某些事件有效,但对某些事件无效,因为它无法映射到特定类,因为它已经在下一个事件中。
注意:我知道 XMLEventReader
但他们中的大多数人都提到它的内存效率不是很高,所以我尝试使用 XMLStreamReader
并完成此操作。
以下是包含事件的示例 XML
文件:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<extension>
<extension>
<c>
<name>CName</name>
<age>CAge</age>
</c>
</extension>
</extension>
<extension>
<b>
<name>BName</name>
<age>BAge</age>
</b>
</extension>
<a>
<name>AName</name>
<age>AAge</age>
</a>
<extension>
<b>
<name>BName</name>
<age>BAge</age>
</b>
</extension>
我有 3 个与它们对应的类,它们将用于 unmarshalling
:
@XmlRootElement(name = "a")
@XmlAccessorType(XmlAccesstype.FIELD)
@XmlType(name = "a",propOrder = {"name","age"})
public class A
{
private String name;
private String age;
//Getter,Setter and other constructors
}
@XmlRootElement(name = "extension")
@XmlAccessorType(XmlAccesstype.FIELD)
@XmlType(name = "extension","age"})
public class B
{
@XmlPath("b/name/text()")
private String name;
@XmlPath("b/age/text()")
private String age;
//Getter,"age"})
public class C
{
@XmlPath("extension/c/name/text()")
private String name;
@XmlPath("extension/c/age/text()")
private String age;
//Getter,Setter and other constructors
}
以下是我将用于 Main
的 unmarshalling
类:
public class Main{
private Unmarshaller unmarshaller = null;
private JAXBContext jaxbContext = null;
public void unmarshaller(InputStream xmlStream) throws IOException,XMLStreamException,JAXBException {
final XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
final XMLStreamReader streamReader = xmlInputFactory.createXMLStreamReader(xmlStream);
//Navigate to next and start of the XML Elements
streamReader.next();
//Read Until the end of the file
while (streamReader.hasNext()) {
//Check if the element is "extension" if so its Class B or C
if (streamReader.isstartElement() && streamReader.getLocalName().equalsIgnoreCase("extension")) {
//Check if the next element also has "extension" if so its Class C
//This is IMPORTANT step for mapping b/w Class B & C which is confusing me
streamReader.next();
if (streamReader.isstartElement() && streamReader.getLocalName().equalsIgnoreCase("extension")) {
//If there is 2 extension tag then its Class C
classspecifier(C.class);
final C cInfo = unmarshaller.unmarshal(streamReader,C.class).getValue();
System.out.println(cInfo);
}else{
//If there is no "extension" tag then its Class B
//THIS IS WHERE ITS FAILING: IF ITS NOT CLASS C THEN IT WOULD COME HERE BUT SINCE I HAVE
//ALREADY MOVED TO NEXT ELEMENT TO CHECK IF ITS "extension" ITS UNABLE TO MAP THE WHOLE CLASS TO CLASS B
classspecifier(B.class);
final B bInfo = unmarshaller.unmarshal(streamReader,B.class).getValue();
System.out.println(bInfo);
}
}else if(streamReader.isstartElement() && streamReader.getLocalName().equalsIgnoreCase("a")){
//If there is no "extension" then its class A
classspecifier(A.class);
final A aInfo = unmarshaller.unmarshal(streamReader,A.class).getValue();
System.out.println(aInfo);
}
}
}
//Method to initialize the JAXBContext and Unmarshaller based on the incoming eventType
private void classspecifier(Class eventTypeClass) throws JAXBException {
this.jaxbContext = JAXBContext.newInstance(eventTypeClass);
unmarshaller = jaxbContext.createUnmarshaller();
}
public static void main(String args[]){
try{
InputStream xmlStream = Main.class.getClassLoader().getResourceAsstream("InputEPCISEvents.xml");
unmarshaller(xmlStream);
} catch (Exception e) {
System.out.println(e);
e.printstacktrace();
}
}
}
我面临的问题是区分 B
和 C
类。
- 我需要检查传入的
localName
是否为extension
。 - 如果是
extension
,那么我需要检查下一个元素localName
是否也是extension
。 - 如果是,则为
class C
,否则为class B
。 - 因为在
Step-2
中,我已经移至streamreader.next()
,如果元素不是extension
,则无法将其映射到class B
,因为我已移至 { {1}} 元素,它没有整个类。
我正在寻找一些可以执行以下操作的解决方案:
- 如果第二次验证中的元素不是
next()
,则返回前一个元素,然后将整个类分配给extension
。 - 在进行检查时将
class B
分配给streamReader
,以便您在tempreader
中前进。但这也失败了。
有没有办法回到流中的前一个元素,否则我该如何解决这个问题?我希望我能够提供一个完整的解释。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。