尝试将XML值转换为地图

时间:2019-05-28 15:41:48

标签: java xml dictionary

我已经看到很多类似的问题,这些问题一直困扰着我,但最终我不得不开始在递归的解决方案之上构建一个我想避免的解决方案。

我有一个要转换为地图的XML文件。

除了一件事之外,结构是未知的

<items>
<item>
{section to be converted to map}
</item>
<item>
{section to be converted to map}
</item>
</items>

我见过的所有解决方案似乎都是将整个事物转换成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}}

,依此类推,在移至下一张地图之前,我可以分别处理和推送每张地图。如果有一个可以轻松处理此问题的库,我很乐意朝那个方向指出。

2 个答案:

答案 0 :(得分:1)

您可以使用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}

答案 1 :(得分:0)

您的地图定义看起来像JSON,只需convert your XML into JSON