xml转java实体对象遇到的大坑,xmlns属性

本文讲述了作者在使用mvnorg.cyclonedx:cyclonedx-maven-plugin生成BOM.xml后,遇到的关于JAXB映射XML结构、命名空间处理和元素嵌套等问题,最终通过自定义XMLFilter解决XML解析时忽略命名空间的问题。
摘要由CSDN通过智能技术生成

背景:
使用mvn org.cyclonedx:cyclonedx-maven-plugin:makeBom命令,在代码各个module的target下生成了bom.xml和bom.json。可以用来统计项目使用了那些组件。之前讲过统计bom.json。这此讲讲统计bom.xml我遇到的大坑。
先根据xml文件定义实体类,使用JAXB将实体类与xml进行匹配,使用注解 @XmlRootElement(name = “AA”)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlAttribute(name = “BB”)
@XmlElement(name = “CC”)
@XmlElementWrapper(name = “DDD”)
所有注解使用方法,自行百度,此处不再赘述。

我遇到的问题:

bom.xml的根节点如下
<bom serialNumber="urn:uuid:dddd3333333333" version="1" xmlns="http://cyclonedx.org/schema/bom/1.4">
... ...
</bom>
  1. @XmlElement和@XmlValue不能一起使用
  2. 没使用@XmlAccessorType(XmlAccessType.FIELD)时候,存在层级关系的属性,会报错存在两个同名标签对象。
  3. 一直报错:unexpected element (uri:“http://cyclonedx.org/schema/bom/1.4”, local:“bom”). Expected elements are <{}bom>
    第三个问题困扰了我好久,
    解决1:按照网上写法,在根节点使用@XmlRootElement(name = “AA”,namespace=“http://cyclonedx.org/schema/bom/1.4”),虽然不报错了,因为bom.xml的层级很复杂,出现根节点内的对象节点全部返回null。
    解决2:尝试将根bom清理为最干净,简单的xml。并删掉上面的namespace=“http://cyclonedx.org/schema/bom/1.4”,然后将bom的属性标签逐步恢复。
    <bom>
    ... ...
    </bom>
    
    终于发现,删掉命名空间xmlns=“http://cyclonedx.org/schema/bom/1.4”,就能解决问题。那么,代码中如何在读取bom.xml的是,忽略命名空间xmlns呢?
    上代码
//创建filter,重点似乎uri为“”
public class NamespaceFilter extends XMLFilterImpl {
   @Override
   public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
       super.startElement("", localName, qName, atts);
   }
}

//xml对象转化为实体对象工具类
@SneakyThrows
   public static Object convertXmlFileToObject(Class<?> clazz, String xmlPath) {

       JAXBContext context = JAXBContext.newInstance(clazz);
       Unmarshaller unmarshaller = context.createUnmarshaller();
       // 创建一个SAXParser,并将自定义的XMLFilter设置给它
       SAXParserFactory spf = SAXParserFactory.newInstance();
       SAXParser sp = spf.newSAXParser();
       XMLReader xr = sp.getXMLReader();
       NamespaceFilter filter = new NamespaceFilter();
       filter.setParent(xr);

       // 创建一个SAXSource,并将XMLReader设置为过滤器
       InputSource inputSource = new InputSource(new FileInputStream(xmlPath));
       SAXSource saxSource = new SAXSource(filter, inputSource);

       // 使用SAXSource和Unmarshaller将XML转换为Java对象
       Object xmlObject = unmarshaller.unmarshal(saxSource);
//        File xmlFile = new File(xmlPath);
//        Object xmlObject = unmarshaller.unmarshal(xmlFile);
       return xmlObject;
   }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值