使用 STAX 解析器将 XML 解组为三个不同对象的列表

2024-02-17

有没有一种方法可以使用 STAX 解析器来有效地解析具有不同类 (POJO) 的多个对象列表的 XML 文档。 我的 XML 的确切结构如下(类名不是真实的)

<?xml version="1.0" encoding="utf-8"?>
<root>
    <notes />
    <category_alpha>
        <list_a>
            <class_a_object></class_a_object>
            <class_a_object></class_a_object>
            <class_a_object></class_a_object>
            <class_a_object></class_a_object>
            .
            .
            .
        </list_a>
        <list_b>
            <class_b_object></class_b_object>
            <class_b_object></class_b_object>
            <class_b_object></class_b_object>
            <class_b_object></class_b_object>
            .
            .
            .
        </list_b>
    </category_alpha>
    <category_beta>
        <class_c_object></class_c_object>
        <class_c_object></class_c_object>
        <class_c_object></class_c_object>
        <class_c_object></class_c_object>
        <class_c_object></class_c_object>
        .
        .
        .
        .
        .
    </category_beta>
</root>

我一直在使用 STAX Parser,即 XStream 库,链接:XStream https://x-stream.github.io/

只要我的 XML 包含一类对象的列表,它就绝对可以正常工作,但我不知道如何处理包含不同类的对象列表的 XML。

任何帮助将不胜感激,如果我没有提供足够的信息或者我没有正确地表达问题,请告诉我。


您可以使用声明式流映射 (DSM) https://mfatihercik.github.io/dsm流解析库可以轻松地将复杂的 XML 转换为 java 类。它使用 StAX 来解析 XML。

我跳过获取notes标签并在里面添加一个字段类_x_对象用于演示的标签。

这是 XML:

<?xml version="1.0" encoding="utf-8"?>
<root>
    <notes />
    <category_alpha>
        <list_a>
            <class_a_object>
                <fieldA>A1</fieldA>
            </class_a_object>
            <class_a_object>
                <fieldA>A2</fieldA>
            </class_a_object>
            <class_a_object>
                <fieldA>A3</fieldA>
            </class_a_object>

        </list_a>
        <list_b>
            <class_b_object>
                <fieldB>B1</fieldB>
            </class_b_object>
            <class_b_object>
                <fieldB>B2</fieldB>
            </class_b_object>
            <class_b_object>
                <fieldB>B3</fieldB>
            </class_b_object>
        </list_b>
    </category_alpha>
    <category_beta>
        <class_c_object>
          <fieldC>C1</fieldC>
        </class_c_object>
        <class_c_object>
          <fieldC>C2</fieldC>
        </class_c_object>
        <class_c_object>
          <fieldC>C3</fieldC>
        </class_c_object>
    </category_beta>
</root>

首先,您必须以 yaml 或 JSON 格式定义 XML 数据和类字段之间的映射。

以下是映射定义:

result:     
   type: object
   path: /root   
   fields:
     listOfA:
       type: array
       path: .*class_a_object  # path is regex
       fields:
          fieldOfA:
            path: fieldA
     listOfB:
       type: array
       path: .*class_b_object
       fields:
          fieldOfB:
            path: fieldB 
     listOfC:
       type: array
       path: .*class_c_object
       fields:
          fieldOfC:
            path: fieldC 

您想要反序列化的 Java 类:

public class Root {
    public List<A> listOfA;
    public List<B> listOfB;
    public List<C> listOfC;

    public static class A{
        public String fieldOfA;
    }
    public static class B{
        public String fieldOfB;
    }
    public static class C{
        public String fieldOfC;
    }

}   

解析XML的Java代码:

DSM dsm=new DSMBuilder(new File("path/to/mapping.yaml")).setType(DSMBuilder.TYPE.XML).create(Root.class);
Root root =  (Root)dsm.toObject(xmlFileContent);
// write root object as json
dsm.getObjectMapper().writerWithDefaultPrettyPrinter().writeValue(System.out, object);

这是输出:

{
  "listOfA" : [ {"fieldOfA" : "A1"}, {"fieldOfA" : "A2"}, {"fieldOfA" : "A3"} ],
  "listOfB" : [ {"fieldOfB" : "B1"}, {"fieldOfB" : "B2"}, "fieldOfB" : "B3"} ],
  "listOfC" : [ {"fieldOfC" : "C1"}, {"fieldOfC" : "C2"}, {"fieldOfC" : "C3"} ]
}

UPDATE:

据我从您的评论中了解到,您希望将大型 XML 文件作为流读取。并在读取文件时处理数据。

DSM 允许您在读取 ​​XML 的同时处理数据。

声明三个不同的函数来处理部分数据。

FunctionExecutor processA=new FunctionExecutor(){
            @Override
            public void execute(Params params) {

                Root.A object=params.getCurrentNode().toObject(Root.A.class);

                // process aClass; save to db. call service etc.
            }
        };
FunctionExecutor processB=new FunctionExecutor(){
            @Override
            public void execute(Params params) {

                Root.B object=params.getCurrentNode().toObject(Root.B.class);

                // process aClass; save to db. call service etc.
            }
        };

FunctionExecutor processC=new FunctionExecutor(){
            @Override
            public void execute(Params params) {

                Root.C object=params.getCurrentNode().toObject(Root.C.class);

                // process aClass; save to db. call service etc.
            }
        };

向 DSM 注册功能

 DSMBuilder builder = new DSMBuilder(new File("path/to/mapping.yaml")).setType(DSMBuilder.TYPE.XML);

       // register function
        builder.registerFunction("processA",processA);
        builder.registerFunction("processB",processB);
        builder.registerFunction("processC",processC);

        DSM dsm= builder.create();
        Object object =  dsm.toObject(xmlContent);

更改映射文件以调用注册函数

result:     
   type: object
   path: /root   
   fields:
     listOfA:
       type: object
       function: processA  # when 'class_a_object' tag closed processA function will be executed.
       path: .*class_a_object  # path is regex
       fields:
          fieldOfA:
            path: fieldA
     listOfB:
       type: object
       path: .*class_b_object
       function: processB# register function
       fields:
          fieldOfB:
            path: fieldB 
     listOfC:
       type: object
       path: .*class_c_object
       function: processC# register function
       fields:
          fieldOfC:
            path: fieldC 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 STAX 解析器将 XML 解组为三个不同对象的列表 的相关文章

随机推荐

  • 查找fs:28h的内存地址

    我为了好玩而使用 gdb 调试程序 并使用堆栈保护 以便它从 fs 28h 将金丝雀写入堆栈 出于好奇 我试图找到 fs 28h 指向的内存地址 我遇到两个问题 首先 gdb 无法显示 gdtr ldtr 中的值 因为它不在环零中运行 第二
  • Android Vitamio 库使 apk 太大

    我正在尝试使用 Vitamio 库 没有 Vitamio 的情况下 我的 apk 大约有 400k 当我添加 Vitamio 的库时 它变得超过 11 MB 我只想使用Vitamio的videoView 有什么方法可以自定义库吗 我开始从库
  • 如何在空手道框架中使用“faker”库?

    我想使用 faker 库在 JSON 文件中生成虚假数据 如下所示 在 karate config js 中 我执行以下操作 var faker require faker 在示例 json 中 firstName faker name f
  • 为什么 .net 中的对象引用错误异常不告诉我哪个对象为空?

    也许问这个问题暴露了我对这个过程缺乏了解 但话又说回来 没有更好的理由来问了 跟踪这些可能会令人沮丧 因为堆栈跟踪可以帮助我知道从哪里开始查找 但不知道哪个对象为空 这里到底发生了什么 是因为变量名称没有捆绑在可执行文件中吗 使用全面优化构
  • 如何检测壁纸何时更改(Windows XP 或更高版本)?

    我已经弄清楚如何更改桌面壁纸 互联网上有几十个示例 我仍然困惑的一件事是 如何检测壁纸何时发生变化 比如通过显示控制面板或其他程序更改它 在 NET 中添加 WM SETTINGCHANGE SystemEvents UserPrefere
  • 信任文件上传的“内容类型”

    如果我支持 REST API 用户上传内容 主要是图像和视频 是吗 safe信任Content Type他们在 分段 上传中声明 或者我应该对内容运行某种 媒体类型检测 例如使用 Apache Tika 以确保声明的媒体类型与检测到的实际媒
  • 将 Java 6 代码向后移植到 Java 5 的简单方法?

    我们已经使用 Java 开发基于 Windows 的应用程序有一段时间了 但现在我们想要制作一个 mac 端口 并且必须反转 Java 6 和 Java 5 的代码 有没有什么简单的方法可以做到这一点 而不是重新编写 编码Java 6具体代
  • postgresql json 聚合

    我使用的是 postgres 9 4 我有以下查询 SELECT pid code name FROM activity SELECT code FROM project projects WHERE activity pcode proj
  • 尝试下载服务器生成的 .zip 文件时出现“错误网关错误 502”

    我在尝试下载服务器生成的 zip 文件时收到 错误网关错误 502 我已经隔离了导致错误的行 它是 zip gt addFile thumb gt loadVersion version id rank thumb gt filename
  • 如何制作一个按钮来打开我的网络应用程序的新实例?

    我制作了一个渐进式网络应用程序 可以从浏览器安装并离线工作 http taiwamaker netlify app 我想在主导航中创建一个按钮 单击该按钮将打开一个新的应用程序窗口 我不想在 chrome 选项卡中打开窗口 在我的计算机 l
  • DLL LNK2019 错误(未解决的外部错误 __imp)

    好吧 我基本上继承了一堆被告知要修复的代码 因为它在几个月前曾经可以工作 但现在却不能 该程序本身似乎充满了链接错误 我能够修复其中的一些错误 但是我遇到了 LNK2019 未解决的外部 imp 错误 其中 main 中使用的某些函数未解决
  • android:我可以为 viewflipper 的不同子级使用不同的类吗

    我有不同的屏幕可以在 Android 应用程序中工作 我为此使用 ViewFlipper 我决定为不同观点的孩子使用不同的班级 public main extends Activity public void onCreate Bundle
  • C++ 模板递归检查 std::tuple 中的类型

    include
  • 我可以用 swift 协议支持多重继承吗?

    在 Swift 中 通过使用扩展 您可以在 协议 中给出方法体 在我的代码中 我可以给出方法主体 请参阅 protocol Test1 func display extension Test1 func display print disp
  • Java几何库[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 Java 有可用的几何库吗 我正在寻找解决方案来获取两个几何对象之间的交点 JTS https github com locationtech jts
  • Heroku 无法找到 XML 配置文件

    我将 Spring 应用程序上传到 Heroku 但应用程序崩溃并出现以下错误 java io FileNotFoundException class path resource com myname myapp config dao co
  • 创建自定义注释 ButterKnife

    我正在尝试为 ButterKnife 创建自定义侦听器注释 但无法使其工作 这是我的注释 Target ElementType METHOD Retention RetentionPolicy CLASS ListenerClass tar
  • Monotouch:了解基础属性

    您能给我解释一下以下属性吗 1 MonoTouch Foundation Register SomeClass 该属性仅用于 IB 的寄存器类吗 当我以编程方式扩展 iOS 类时 是否必须使用此类 2 Export initSomethin
  • 如何在 Android Studio 首次运行时禁用下载组件

    我提取Android Studio IDE 135 1740770 还为 SDK 安装了这些软件包 Tools Android SDK工具24 1 2 Android SDK平台 工具22 Android SDK构建工具22 0 1 Ext
  • 使用 STAX 解析器将 XML 解组为三个不同对象的列表

    有没有一种方法可以使用 STAX 解析器来有效地解析具有不同类 POJO 的多个对象列表的 XML 文档 我的 XML 的确切结构如下 类名不是真实的