我见过很多类似的问题,这些问题一直让我半途而废,但我最终开始不得不在我试图避免的基础上构建递归解决方案。
我有一个 XML 文件想要转换为 map 。
除了一件事之外,结构未知
<items>
<item>
{section to be converted to map}
</item>
<item>
{section to be converted to map}
</item>
</items>
我见过的所有解决方案似乎都是将整个事物转换为 map ,或者手动解析每个属性/值。
我想知道是否有一种方法可以说...
跳转到项目,跳转到每个项目,将每个项目转换为 map ,然后我可以单独处理每个 map 。
我正在流式传输一个可能很大的文件,因此不想将整个文件保存在内存中,一次只保存一项。
我尝试使用 xmleventreader 来执行此操作,但陷入了递归噩梦中。该项目供事件读取器查找单个项目,并在这些单个项目上进行处理,但没有找到任何有关如何捕获每个值之间的内容以便稍后将其作为 XML 进行处理的文档。
private void parseItemList(MultipartFile file) {
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
try {
XMLEventReader xmlEventReader = xmlInputFactory.createXMLEventReader(file.getInputStream());
processItems(xmlEventReader);
} catch (FileNotFoundException | XMLStreamException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
这个想法是转换:
<items>
<item>
<id>1</id>
<value>4</value>
</item>
<item>
<id>2</id>
<attributes>
<value>5</value>
</attributes>
</item>
</items>
进入
{id: 1, value: 4}
{id: 2, attributes{value: 5}}
等等,我可以在移动到下一个之前单独处理和推送每个 map 。如果有一个库可以轻松处理这个问题,我很乐意指出这个方向。
最佳答案
您可以使用Declarative Stream Mapping (DSM)流解析库可以轻松地将复杂的 XML 转换为 java 类。您可以在读取xml文档的同时,调用自定义函数处理部分数据。
首先,您必须以 yaml 格式定义 XML 数据和类字段之间的映射。
以下是 XML 的映射定义。
result:
type: object # type is the object to consume low memory.
#you will get an object(Map) as a result not List
path: /items/item
function: processFunction # call registered ' processFunction' for every 'items/item'
fields:
value: # not exist for second item it is skiped
id:
attributes: # not exist for first item so it is skiped
type: object
fields:
value:
创建流程函数:
FunctionExecutor processFunction=new FunctionExecutor() {
@Override
public void execute(Params params) {
Node node = params.getCurrentNode();
// deserialize to your class
//YourClass.class=node.toObject(YourClass.class);
//or
// directly access data
System.out.println(node.getData());
}
}
解析 XML 的 Java 代码:
DSMBuilder builder = new DSMBuilder(new File("path/to/mapping.yaml")).setType(DSMBuilder.TYPE.XML);
// register function
builder.registerFunction("processFunction",processFunction);
DSM dsm= builder.create();
Object object = dsm.toObject(xmlContent);
// type of object varibale is a Map<String,Obejct>
输出:
{id=1, value=4}
{id=2, attributes={value=5}}
更新:
如果您希望“item”标签和“attributes”标签中的值标签处于同一级别,您可以按如下方式更改映射定义
result:
type: object # it is defiden as object for low memory.
#you will get an object(Map) as a result not List
path: /items/item
function: processFunction # call registered '' processFunction for every 'items/item'
fields:
id:
value:
path: .*value # path is regex. take both value tag in item and attributes tags
输出:
{id=1, value=4}
{id=2, value=5}
关于java - 尝试将 XML 值转换为映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56345742/