【java解析XML文件遇到的小坑】

文章讲述了如何使用Java的JAXB库解析XML文件,将XML的节点映射到Java对象的属性。在解析过程中遇到了属性重名的问题,通过添加`@XmlAccessorType(XmlAccessType.FIELD)`注解解决了问题,确保每个XML节点正确映射到对应的字段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求描述

简单描述一下需求,用java代码解析xml文件,将xml中的每个节点映射成java对象中的属性,节点值映射成属性值。

XML文件案例

<?xml version="1.0" encoding="UTF-8" ?>
<USER>
    <NAME>张三</NAME>
    <PHONE>18326395619</PHONE>
    <DESC>法外狂徒,张三!</DESC>
</USER>

代码

java对象代码

package com.bai.study_springboot.bean;

import lombok.Data;
import lombok.ToString;

import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * author liuBai
 * 2023/5/18 9:28
 */
@Data
@ToString
@XmlRootElement(name = "USER")
public class XmlUserBean {

    @XmlElement(name = "NAME")
    private String name;

    @XmlElement(name = "PHONE")
    private String phone;

    @XmlElement(name = "DESC")
    private String desc;

}

转换操作业务代码

package com.bai.study_springboot.bean;


import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import java.io.*;

public class XmlUserBeanTest {

    public static void main(String[] args) {
    	//文件地址需要根据你的xml文件实际位置,做改变
        File file = new File("D:\\project_code\\project_java\\project_my\\study_test_demo\\study-springboot-demo\\study-springboot-demo02\\src\\main\\resources\\user.xml");
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)))) {
            /*StringBuffer buffer = new StringBuffer("");
            while (reader.ready()) {
                buffer.append(reader.readLine());
            }*/
            JAXBContext jaxbContext = JAXBContext.newInstance(XmlUserBean.class);
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            Object unmarshal = unmarshaller.unmarshal(reader);
            System.out.println(unmarshal);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

遇到的小坑

在这里插入图片描述
报错了,类的两个属性具有相同的名称,java对象的每个属性都会报错,有两个同名属性。

先上解决办法

在java类对象上添加注解@XmlAccessorType(value = XmlAccessType.FIELD)
代码如下:

package com.bai.study_springboot.bean;

import lombok.Data;
import lombok.ToString;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * author liuBai
 * 2023/5/18 9:28
 */
@Data
@ToString
@XmlAccessorType(value = XmlAccessType.FIELD)
@XmlRootElement(name = "USER")
public class XmlUserBean {

    @XmlElement(name = "NAME")
    private String name;

    @XmlElement(name = "PHONE")
    private String phone;

    @XmlElement(name = "DESC")
    private String desc;

}

分析原有

在分析原因之前,先了解一下@XmlAccessorType注解,@XmlAccessorType注解的源码

@Inherited @Retention(RUNTIME) @Target({PACKAGE, TYPE})
public @interface XmlAccessorType {

    /**
     * Specifies whether fields or properties are serialized.
     *
     * @see XmlAccessType
     */
    XmlAccessType value() default XmlAccessType.PUBLIC_MEMBER;
}

看源码可以知道,这是一个类级别的注解(注解在类上的注解),该注解的作用是,定义一个类中的何种类型需要映射到XML。解释起来有点拗口,可以通过它的属性值更好理解这个参数的意义。
参数 value
可以接受4个指定值,这几个值是枚举类型,方便调用:

  • XmlAccessType.FIELD:映射这个类中的所有字段到XML
  • XmlAccessType.PROPERTY:映射这个类中的属性(get/set方法)到XML
  • XmlAccessType.PUBLIC_MEMBER:将这个类中的所有public的field或property同时映射到XML(默认)
  • XmlAccessType.NONE:不映射

然后在看一段解析XML文件时的源码
在这里插入图片描述
当我们的java类没有加@XmlAccessorType 注解的时候,截图中的两个方法都会生效,因为XmlAccessType的value值会是默认PUBLIC_MEMBER。这样就会导致上述的报错了。
当我们添加了注解@XmlAccessorType(value = XmlAccessType.FIELD)时,截图中的只会有第一个方法生效,这样就可以避免上述报错了。

截图中两个方法的源码,这里就不再贴出了!感兴趣的小伙伴,可自行翻看学习

(此处引用了:https://www.w3cschool.cn/jaxb2/jaxb2-q85r2zok.html)@XmlAccessorType注解解释

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值