我有一个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", propOrder = {"name","age"})
public class B
{
@XmlPath("b/name/text()")
private String name;
@XmlPath("b/age/text()")
private String age;
//Getter, Setter and other constructors
}
@XmlRootElement(name = "extension")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "extension", propOrder = {"name","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();
}
}
}
我面临的问题是 classB
和C
.
- 我需要检查传入
localName
的是否是extension
. - 如果是,
extension
那么我需要检查下一个元素localName
是否也是extension
. - 如果是,那么
class C
如果不是,那么class B
。 - 因为在
Step-2
我已经移动到streamreader.next()
并且如果元素不是extension
那么它无法将它映射到class B
因为我已经移动到next()
元素并且它没有整个类。
我正在寻找一些可以执行以下操作的解决方案:
- 如果第二次验证中的元素不是
extension
,则返回上一个元素,然后将整个类分配给class B
. - 在进行检查时分配
streamReader
to ,以便您前进。但这也失败了。tempreader
tempreader
有没有办法回到流中的前一个元素,否则我该如何解决这个问题?我希望我能够提供一个完整的解释。