java中XML格式转换

        之前很少用xml格式,但是有些老系统还是需要使用xml格式进行对接,所以干脆总结一下,方便以后使用。

关于xml:

即可扩展标记语言,xml是互联网数据传输的重要工具,它可以跨越互联网任何的平台,不受编程语言和操作系统的限制,可以说它是一个拥有互联网最高级别通行证的数据携带者。xml是当前处理结构化文档信息中相当给力的技术,xml有助于在服务器之间穿梭结构化数据,这使得开发人员更加得心应手的控制数据的存储和传输。

Xml用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。Xml是标准通用标记语言(SGML)的子集,非常适合Web传输。XML提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。

也就是说xml有一个很大作用就是,跨平台跨系统之间的传输,这点跟json数据类似,不同的系统都能识别这种数据类型传输的信息。

一、xml格式: 

一个xml文档必须要有第一行的声明和它的文档元素的描述信息就可以了:

1)xml声明:

也就是说第一行必须是声明。
声明的格式:

version:代表文档符合xml1.0规范
encoding:代表文档字符编码,默认编码为UTF-8

2)根元素

声明下方的标签就是根元素。

 根元素结构如上所示,它是xml文档里面唯一的;它的开始是放在最前面,结束是放在最后面。

3)元素

根元素中包裹的就是元素:

结构如上图所示,需要注意的是:
1、所有xml的元素都必须有结束标签
2、xml标签区分大小写,也就是对大小写敏感,如果大小写不一致会被认定不是同一个。
 

 3、xml必须正确地嵌套,要按照顺序嵌套:

4、元素的命名规则:
        ·名称中可以包含字母、数字或者其他的字符;
        ·名称不能以数字或者标点符号开始;
        ·名称中不能包含空格。
5、空元素格式:

6、属性:

  • 语法

    <元素名 属性名=“属性值”/>

    例:<Student ID=“S100”>

           <Name>Tom</Name>

           </Student>

  • 注意:

    属性值用双引号包裹;一个元素可以有多个属性,它的基本格式为:
            <元素名 属性名=“属性值” 属性名=“属性值”>;

    属性值中不能够直接包含<.”,&。

7、实体:

在xml中,一些字符拥有特殊的意义。如果把字符“<”放在xml元素中,会发生错误,这是因为解析器会把它当作新元素的开始,这样会产生xml错误:

为了避免这个错误,请用实体引用来代替“<”字符:

xml中5个预定义实体

8、注释

注:注释内容中不要出现”--”;不要把注释放在标签中间;注释不能嵌套。

 

9、总结:

(1)xml描述的是文档的内容与语义,而不是文档应当如何显示;

(2)格式正规(well formed)的xml文档,遵循如下规则的xml文档称为格式正规的xml文档:

        ·必须有xml声明语句;
        ·必须有且仅有一个根元素;
        ·标签大小写敏感;
        ·属性值用双引号;
        ·标签成对;
        `空标签关闭;
        `元素正确嵌套。

(3)有效的(valid)xml文档。首先xml文档是个格式正规的xml文档,然后又需要满足DTD的要求,这样的xml文档称为有效的xml文档;

以上就是关于xml格式介绍,其中还有很多细节,没有说,但是本次着重记录在java中的应用与转换,所以还有详细的内容可以自行查阅。

xml详解-CSDN博客

二、使用Jackson解析xml

1)引入依赖:
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.15.1</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.15.1</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
            <version>2.15.1</version>
        </dependency>
2)XmlMapper:

跟jackson解析json格式一样,解析json使用ObjectMapper,解析xml格式主要使用XmlMapper。

主要靠的也是这两个方法:
writeValueAsString():将java对象转换为xml字符串。
readValue():将xml字符串转换为java对象。

其实使用的方式跟 json格式的转换时差不多,用的也是这两个方法,而且用之前最好先进行自定义配置一下,配置的方式跟json中ObjectMapper配置完全适用:

    private static XmlMapper MAPPER = new XmlMapper();

    static  {

        MAPPER = new XmlMapper();
//
//        xmlMapper.setDefaultUseWrapper(false);
//        //字段为null,自动忽略,不再序列化
            xmlMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
//        //XML标签名:使用骆驼命名的属性名,
//        xmlMapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE);
//        //设置转换模式
//        xmlMapper.enable(MapperFeature.USE_STD_BEAN_NAMING);
//        xmlMapper.registerModule(new JavaTimeModule());

        //序列化所有属性,对象中属性为null的时候,会打印该属性为null
        MAPPER.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        //序列化时,对象中属性为null的时候,会忽略该属性
//        MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        //序列化时,若POJO对象的属性值为"",序列化时不进行显示
//        MAPPER.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        //序列化时,忽略值为默认值的属性
//        MAPPER.setDefaultPropertyInclusion(JsonInclude.Include.NON_DEFAULT);
        //美化输出,转换为格式化的json
        MAPPER.enable(SerializationFeature.INDENT_OUTPUT);


        //在遇到未知属性的时候不抛出异常。
        MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        //允许没有引号的字段名(非标准)出现。
        MAPPER.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        //允许单引号(非标准)
        MAPPER.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        // 允许整数以0开头
        MAPPER.configure(JsonReadFeature.ALLOW_LEADING_ZEROS_FOR_NUMBERS.mappedFeature(), true);
        // 允许出现特殊字符和转义符
        //mapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);这个已经过时。
        MAPPER.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);


        //关于Date类型参数序列化配置
        //取消时间的转化格式,默认是时间戳,可以取消,同时需要设置要表现的时间格式
        MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
        MAPPER.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
//        MAPPER.setDateFormat(new SimpleDateFormat(DatePattern.NORM_DATETIME_PATTERN));
        //关于localDateTime类型参数序列化配置,不配会报错
//        JavaTimeModule timeModule = new JavaTimeModule();
//        //反序列化
//        timeModule.addDeserializer(LocalDateTime.class, new
//                LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
//        //系列化
//        timeModule.addSerializer(LocalDateTime.class, new
//                LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
//        MAPPER.registerModule(timeModule);
        //上面的配置都不需要了,直接创建配置类即可
        MAPPER.registerModule(new SatiJavaTimeModule());


        SimpleModule simpleModule = new SimpleModule();
        //将Long类型序列化为String类型
        simpleModule.addSerializer(Long.class, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
        //将BigDecimal类型序列化为String类型
        simpleModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);

        simpleModule.addSerializer(BigDecimal.class,new BigDecimalSerializer());
        simpleModule.addSerializer(Long.class, new LongSerializer());
        MAPPER.registerModule(simpleModule);
        MAPPER.findAndRegisterModules();



    }

然后就可以直接进行转换了:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {

    private String name;

    private String age;

    private LocalDateTime time;

    private List<String> strings;
}
        ArrayList<String> list = new ArrayList<>();
        list.add("111");
        list.add("111");
        list.add("111");

        Student student = new Student("姓名", "年龄", LocalDateTime.now(),list);

        String xml = MAPPER.writeValueAsString(student);
        System.out.println(xml);

        Student student1 = MAPPER.readValue(xml, Student.class);
        System.out.println(student1);

这是最简单的转换方式 。

3)jackson解析xml相关注解:
  • @JacksonXmlRootElement
    指定生成xml根标签的名字。用于类名,是xml最外层的根节点。注解中有localName属性,该属性如果不设置,那么生成的XML最外面就是Clazz。
  • @JacksonXmlProperty
    指定包装标签名,或者指定标签内部属性名。该注解通常可以不需要,若不用,生成xml标签名称就是实体类属性名称。但是如果你想要你的xml节点名字,首字母大写。比如例子中的Content,那么必须加这个注解,并且注解的localName填上你想要的节点名字。最重要的是实体类原来的属性content必须首字母小写!否则会被识别成两个不同的属性。注解的isAttribute,确认是否为节点的属性,如下图中的“gradeId”。
  • @JacksonXmlElementWrapper
    用于指定List等集合类,外围标签名;用在非集合类上无效。一般用于list,list外层的标签。若不用的话,useWrapping =false。
  • @JacksonXmlText
    指定当前这个值,没有xml标签包裹。用实体类属性上,说明该属性是否为简单内容,如果是,那么生成xml时,不会生成对应标签名称。
  • @JsonIgnore
    忽略该实体类的属性,该注解是用于实体类转json的,但用于转xml一样有效,具体原因个人推测是XmlMapper是ObjectMapper的子类。
  • @JacksonXmlCData
    是为了生成<![CDATA[text]]>。

一共六个注解,比较简约一点,其实主要使用的是这三个:
        根元素:@JacksonXmlRootElement
        根元素中包裹的其他元素:@JacksonXmlProperty
        根元素中包裹的列表元素:@JacksonXmlElementWrapper
        除去这三个还有@JsonIgnore比较常用,用于转xml格式时,忽略这个字段
        @JacksonXmlText这个注解加上之后的效果就是会输出一个没有标签包裹的内容
        @JacksonXmlCData主要是转换xml时,标签里面的内容指定。

示例:

@Data
@AllArgsConstructor
@NoArgsConstructor
@JacksonXmlRootElement(localName = "ROOT")
public class Student {
    @JacksonXmlProperty(localName = "NAME",isAttribute = true)
    private String name;

    @JacksonXmlProperty(localName = "AGE")
    private String age;

    @JacksonXmlProperty(localName = "TIME")
    private LocalDateTime time;

    @JacksonXmlProperty(localName = "STRING")
    @JacksonXmlElementWrapper(localName = "STRINGS")
    private List<String> strings;
}
        ArrayList<String> list = new ArrayList<>();
        list.add("111");
        list.add("111");
        list.add("111");

        Student student = new Student("姓名", "年龄", LocalDateTime.now(),list);

        String xml = MAPPER.writeValueAsString(student);
        System.out.println(xml);

 @JacksonXmlProperty中的isAttribute = true,这个属性就会成为父标签中的内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/273787.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Word中插入mathtype的行内公式显示不全,设置行距,最小值

Word中插入mathtype的行内公式显示不全 如下图&#xff1a;公式上下被遮住 解决方式&#xff1a; 设置所在段落的行距&#xff1a;最小值--xx磅。同时取消勾选 “如果定义了文档网格&#xff0c;则对齐到网格” 处理后效果&#xff1a;

Flash芯片W25Q系列驱动注意事项以及跨页读写操作

一、硬件 二、W25Q64简介与API函数 1) W25Q有很多系列&#xff0c;其区别就是存储容量不一样 以我现在使用的举例W25Q64 64指的是64Mbit&#xff0c;不是64M字节要区分清楚 64Mbit 8Mbyte,所以总的容量能存储8MByte 2) W25q64的存储分为块、扇区、页 一页&#xff1…

人类偏好导向:DPO技术重塑SDXL-1.0图像生成

引言 在AI领域&#xff0c;适应和理解人类偏好一直是技术发展的重要方向。斯坦福大学研究团队最近提出的Diffusion-DPO方法&#xff0c;旨在将这一理念应用于图像生成模型&#xff0c;特别是在文本到图像的转换领域。 Huggingface模型下载: https://huggingface.co/mhdang/ A…

windows搭建MySQL 8.25主从配置

1.本次搭建的版本 mysql-8.0.25-win-x64 2.在解压完成后的文件内并没有对应的my.ini的配置文件这个my.ini是需要的主配置文件需要自行创建。 注&#xff1a;安装路径及数据存放路径需根据实际安装情况进行修改&#xff08;其它配置信息可结合实际情况进行修改&#xff09; 3.在…

【Vue】响应式中数组的特殊处理

Vue 响应式中对数组的处理 前两节的内容&#xff1a; Vue 数据劫持 Vue 响应式初步 0. 为什么需要对数组特殊处理&#xff1f; 在响应式初步那一篇文章的最后&#xff0c;我们提到过&#xff0c;需要对数组进行特殊的处理&#xff0c;为什么&#xff1f; 如果仍然用我们之…

vue3(六)-基础入门之自定义组件与插槽、ref通信

一、全局组件 html: <div id"app"><mytemplace></mytemplace> </div>javascript: <script>const { createApp } Vueconst app createApp({})app.component(mytemplace, {template: <div><button>返回</button>…

Resnet

是什么样的原因导致更深的网络导致的训练效果更差呢&#xff1f; 梯度消失和梯度爆炸 随着网络层数的不断加深&#xff0c;梯度消失和梯度爆炸的现象会越来越明显&#xff0c; 梯度消失&#xff1a;假设每一层的误差梯度是一个小于1的数&#xff0c;那么在我们反向传播过程中…

<软考高项备考>《论文专题 - 26 整合管理(4) 》

6 过程5-监控项目工作 6.1 问题 4W1H过程1-制定项目章程做什么跟踪、审查和报告整体项目进展&#xff0c;以实现项目管理计划中确定的绩效目标的过程&#xff1b;作用&#xff1a;①让干系人了解项目的当前状态并认可为处理绩效问题而采取的行动;②通过成本和进度预测&#x…

Docker 高级网络 - 自定义网桥实现容器间通信

目录 一、容器间容通信 1.1、解释 1.2、网络相关操作指令 1.2.1、查看 docker 的网络列表 1.2.2、创建网络自定义桥 1.2.3、删除某一个网络 1.2.4、查看某一个网络细节 1.2.5、运行多个容器在指定的网络中 一、容器间容通信 1.1、解释 简单来讲就是&#xff1a;容器间通…

华为Auth-HTTP服务器任意文件读取漏洞

华为Auth-Http Server 1.0存在任意文件读取&#xff0c;攻击者可通过该漏洞读取任意文件。 1.漏洞级别 高危 2.漏洞搜索 fofa server"Huawei Auth-Http Server 1.0"3.漏洞复现 构造 GET /umweb/passwd HTTP/1.1 Host: User-Agent: Mozilla/5.0 (Macintosh; I…

APP开发详解:数字药店系统源码

数字药店系统的兴起&#xff0c;不仅为消费者提供了更加便捷的购药体验&#xff0c;也为药店管理和药品销售带来了全新的机遇。 一、明确系统的基本功能&#xff1a; 1.用户注册与登录 2.药品浏览与搜索 3.购物车与结算。 4.在线支付与订单管理 二、开发环境与技术栈选择 …

blackbox黑盒监控部署(k8s内)tensuns专用

一、前言 部署在k8s中需要用到deployment、configmap、service服务 二、部署 创建存放yaml的目录 mkdir /opt/blackbox-exporter && cd /opt/blackbox-exporter 编辑blackbox配置文件&#xff0c;使用configmap挂在这 vi configmap.yaml apiVersion: v1 kind: Confi…

c语言-表达式求值

目录 前言一、隐式类型转换1.1 整型提升 二、算术转换三、操作符的属性四、问题表达式总结 前言 表达式求值的顺序一部分由操作符的优先级和结合性决定。 有些表达式的操作数在求值的过程中可能需要转换为其他类型 一、隐式类型转换 隐式类型转换是在编译器自动进行的类型转换…

TYPE C 接口知识

1、Type C 概述 Type-C口有4对TX/RX分线&#xff0c;2对USBD/D-&#xff0c;一对SBU&#xff0c;2个CC&#xff0c;另外还有4个VBUS和4个地线。 当Type-C接口仅用作传输DP信号时&#xff0c;则可利用4对TX/RX&#xff0c;从而实现4Lane传输&#xff0c;这种模式称为DPonly模式…

手持机定制_手持终端_rfid手持终端设备开发解决方案

智物通讯PDA手持终端方案以联发科64位八核MT6771芯片为核心&#xff0c;配备Android 10系统&#xff0c;以提供更高的运行速度和更低的功耗。存储器方面&#xff0c;则有2GB LPDDR332GB eMMC&#xff0c;同时也可选择4GB64GB、8GB128GB的配置&#xff0c;以确保设备的顺畅运行。…

PYTHON基础:python-plotly模拟随机过程

python-plotly模拟掷骰子随机过程 虽然投掷骰子看起来是随机事件&#xff0c;但只要使用正确的算法进行模拟&#xff0c;实际上它可以被精确地预测和分析。在数学领域&#xff0c;人们常常使用概率论和统计学知识来解释各种随机事件的规律和特征。而在赌场等场合&#xff0c;骰…

【教程】将Python转为C语言并编译生成二进制文件

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 本教程以DGL版本的GCN为例&#xff0c;其他也相似。 1、安装cython、gcc&#xff1a; sudo apt install cython gcc -y2、安装DGL、PyTorch&#xff1a; pip3 install torch torchvision torchaudio pip insta…

电商数据分析-03-电商数据采集

参考 最最最全数据仓库建设指南&#xff0c;速速收藏&#xff01;&#xff01; 第1章 数据仓库概念 数据仓库规划 1.1 数仓搭建 我们这里所说的数据仓库&#xff0c;是基于大数据体系的&#xff0c;里面包含标签类目&#xff0c;区别于传统的数据仓库。下面我们来将这张图分解…

信息网络协议基础-IPv6协议

文章目录 概述为什么引入IP服务模型IPv4的可扩展性问题解决方法***CIDR(Classless Inter-Domain Routing, 无类别域间寻路)前缀汇聚***前缀最长匹配***NAT(网络地址转换)存在的问题解决方案路由表配置***局限性IPv6协议头标IPv6地址表示前缀类型单播地址链路局部地址(Link-Loca…

元道经纬相机信息化赋能光伏电站运维管理

近年来&#xff0c;我国光伏产业高速发展&#xff0c;尤其以分布式光伏发电项目增长迅速&#xff0c;为更好服务新能源发电&#xff0c;大力推广电能替代。与此同时&#xff0c;电力企业亟需改变落后的管理模式&#xff0c;借助信息化软件提升管理效率。 为了进一步提升光伏电…