java - Stax 解析两次
问题描述
我正在尝试使用 stax 从下面的 xml 中获取父母,请注意,同一结构中可以有多个父母和孩子。
<sm:Structure>
<sm:Parent>
<sm:parentCode>PARENT-CODE-1</sm:parentCode>
<sm:parentName>PARENT-NAME-1</sm:parentName>
</sm:Parent>
<sm:Child>
<sm:childCode>CHILD-CODE-1</sm:childCode>
<sm:childName>CHILD-NAME-1</sm:childName>
<sm:parentCode>PARENT-CODE-1</sm:parentCode>
</sm:Child>
</sm:Structure>
使用以下代码:
XMLStreamReader xmlr = null;
try {
XMLInputFactory xmlif = XMLInputFactory.newInstance();
File file = new File(fileName);
xmlr = xmlif.createXMLStreamReader(new FileReader(file));
JAXBContext context = JAXBContext.newInstance(type);
Unmarshaller unmarshaller = context.createUnmarshaller();
while (xmlr.hasNext() && (!xmlr.isStartElement() || !xmlr.getLocalName().equalsIgnoreCase(localName))) {
xmlr.next();
}
List<T> objectList = new ArrayList<>();
int numberOfRead = 0, chunkIndex = 0;
StopWatch watch = new StopWatch();
watch.start();
while (xmlr.getEventType() == XMLStreamConstants.START_ELEMENT) {
if (numberOfRead == chunkSize) {
chunkConsumer.consumeChunk(objectList, chunkIndex, chunkSize, breakChildProcessOnParentError));
numberOfRead = 0;
chunkIndex++;
objectList = new ArrayList<>();
}
JAXBElement<T> objNode = unmarshaller.unmarshal(xmlr, type);
T obj = objNode.getValue();
objectList.add(obj);
numberOfRead++;
if (xmlr.getEventType() == XMLStreamConstants.CHARACTERS) {
xmlr.next();
}
}
if (numberOfRead != 0) {
chunkConsumer.consumeChunk(objectList, chunkIndex, chunkSize, breakChildProcessOnParentError));
}
watch.stop();
log.info("Time Elapsed to trigger all " + type.getName() + "-Chunk-Consumers: " +
watch.toSplitString());
} catch (Exception e) {
throw new CustomException("Error during " + type.getName()+ "-Chunk-Consumer process.", e);
} finally {
try {
if (xmlr != null) {
xmlr.close();
}
} catch (Exception exception) {
log.error(exception.getMessage(), exception);
}
}
它有趣地读取了两次父母,第一次没问题,第二次没有 parentName。为什么要解析两次?
解决方案
在一段时间内错过了一个条件,添加解决了我的问题。
while (xmlr.getEventType() == XMLStreamConstants.START_ELEMENT && xmlr.getLocalName().equalsIgnoreCase(localName)) {
推荐阅读
- angular - 如何引用 Leaflet.draw 中已删除的图层?
- javascript - 输入明文时出现错误“文本字符串必须在文本中呈现...”
- r - 如何在r中选择并重复数据框中的多行
- javascript - 当名称字段中存在任何重复值时,无法形成结构和更新标志值
- c++ - 这个函数是返回一个正确的 R 值引用还是返回一个副本?
- excel - How to fix this "ambiguous name detected Worksheet_Change"?
- openedge - FILL-IN基本组件中如何避免千位分隔符
- sql - 在 SQL Server Management Studio (SSMS) 中禁用空白文本的副本
- javascript - ag-grid:key.forEach 在调整列大小时不是函数控制台错误
- nvidia-jetson - Jetson nano 模块与生产开发人员