zoukankan      html  css  js  c++  java
  • Java 解析XML示例

    要解析如下xml

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ns2:FeatureDictionaryResponse xmlns="urn:xxx/Common/MetadataModel"
        xmlns:ns2="urn:xxx/Metadata">
        <ns2:Catalog id="xxxxx-xxxx-xxx-xxxx"/>
        <ns2:Config>
            <ProductSelections>
                <Series id="abc" selectable="false" compound="false" multi="false">
                    <Feature id="Q0001"/>
                    <Feature id="Q0002"/>
                </Series>
                <Series id="def" selectable="false" compound="false" multi="false">
                    <Feature id="G0001"/>
                </Series>
            </ProductSelections>
        </ns2:Config>
    </ns:FeatureDictionaryResponse>

    一种方法是通过DOM解析方式实现,缺点是嵌套层次多导致代码不易读,修改起来麻烦。这里我们用类似反序列化方式来实现。

    一、定义xml节点对应的类

     首先定义最内层节点对应的类:

    package com.example.model;
    
    import lombok.Data;
    
    import javax.xml.bind.annotation.XmlAccessType;
    import javax.xml.bind.annotation.XmlAccessorType;
    import javax.xml.bind.annotation.XmlAttribute;
    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name = "Feature")
    @Data
    public class Feature {
        @XmlAttribute(name = "id")
        protected String id;
    }

    然后定义其父节点对应的类:

    package com.example.model;
    
    import lombok.Data;
    
    import javax.xml.bind.annotation.*;
    import java.util.List;
    
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name = "Series")
    @Data
    public class Series {
        @XmlAttribute
        protected String id;
    
        @XmlElement(name = "Feature")
        private List<Feature> features;
    }

    以此类推

    package com.example.model;
    
    import lombok.Data;
    
    import javax.xml.bind.annotation.XmlAccessType;
    import javax.xml.bind.annotation.XmlAccessorType;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;
    import java.util.List;
    
    @XmlRootElement(name = "ProductSelections")
    @XmlAccessorType(XmlAccessType.FIELD)
    @Data
    public class ProductSelections {
        @XmlElement(name = "Series")
        protected List<Series> series;
    }
    package com.example.model;
    
    import lombok.Data;
    
    import javax.xml.bind.annotation.XmlAccessType;
    import javax.xml.bind.annotation.XmlAccessorType;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;
    
    
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name = "ns2:Config")
    @Data
    public class Config {
    
        @XmlElement(name = "ProductSelections")
        protected ProductSelections productSelections;
    }

    最外层的类

    package com.example.model;
    
    import lombok.Data;
    
    import javax.xml.bind.annotation.XmlAccessType;
    import javax.xml.bind.annotation.XmlAccessorType;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;
    
    
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name = "FeatureDictionaryResponse", namespace = "urn:xxx/Metadata")
    @Data
    public class FeatureDictionaryResponse {
        @XmlElement(name = "Config", namespace = "urn:xxx/Metadata")
        protected Config config;
    }

    由于xml中有自定义命名空间,所以我们需要添加一个package-info.java文件(在IDEA中直接添加会提示命名不合法,所以要手动创建出此文件),其内容如下

    @XmlSchema(namespace = "urn:xxx/Common/MetadataModel",
            elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
            xmlns = {
                    @XmlNs(prefix = "ns2", namespaceURI = "urn:xxx/Metadata")
            })
    package com.example.model;
    
    import javax.xml.bind.annotation.XmlSchema;
    import javax.xml.bind.annotation.XmlNs;

    最后创建一个XmlUtil.java(来源于网上其他博主),提供将字符串解析为对象的方法。

    package com.example.common;
    
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.JAXBException;
    import javax.xml.bind.Marshaller;
    import javax.xml.bind.Unmarshaller;
    import java.io.StringReader;
    import java.io.StringWriter;
    import java.util.Map;
    
    public class XmlUtil {
        /**
         * 将对象直接转换成String类型的 XML输出
         * @param obj
         * @return
         */
        public static String convertToXml(Object obj) { // 创建输出流
            StringWriter sw = new StringWriter();
            try {
                // 利用jdk中自带的转换类实现
                JAXBContext context = JAXBContext.newInstance(obj.getClass());
                Marshaller marshaller = context.createMarshaller();// 格式化xml输出的格式
                marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
                // 将对象转换成输出流形式的xml
                marshaller.marshal(obj, sw);
            } catch (JAXBException e) {
                e.printStackTrace();
            }
            return sw.toString();
        }
    
        public static String mapToXml(Map<String, Object> map) {// 创建输出流
            StringBuilder sb = new StringBuilder();
            sb.append("<xml>
    ");
            //
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                sb.append("<").append(entry.getKey()).append(">");
                sb.append(entry.getValue().toString());
                sb.append("</").append(entry.getKey()).append(">
    ");
            }
            sb.append("</xml>
    ");
            return sb.toString();
        }
    
        @SuppressWarnings("unchecked")
        /**
         将String类型的xml转换成对象
         */
        public static <T> T convertToObj(String xmlStr, Class<T> clazz) {
            T xmlObject = null;
            // 进行将Xml转成对象的核心接口
            try {
                JAXBContext context = JAXBContext.newInstance(clazz);
                Unmarshaller unmarshaller = context.createUnmarshaller();
                StringReader sr = new StringReader(xmlStr);
                xmlObject = (T)
                        unmarshaller.unmarshal(sr);
            } catch (JAXBException e) {
                e.printStackTrace();
            }
            return xmlObject;
        }
    }

    测试:

    package com.example;
    
    import com.example.common.XmlUtil;
    import com.example.model.FeatureDictionaryResponse;
    
    import java.io.BufferedReader;
    import java.io.FileReader;
    
    /**
     * @Author jian.yu
     * @Date 2021/2/4,0004 17:44
     * @Description
     */
    public class App {
        public static void main(String[] args) {
            StringBuilder content = new StringBuilder();
            try {
                FileReader reader = new FileReader("D:\Demo\XmlResolve\data.xml");
                BufferedReader br = new BufferedReader(reader);
    
                String line = br.readLine();
                while (line != null) {
                    content.append(line);
                    line = br.readLine();
                }
                br.close();
            } catch (Exception ex) {
                System.out.println(ex);
            }
    
            FeatureDictionaryResponse fd = XmlUtil.convertToObj(content.toString(), FeatureDictionaryResponse.class);
            System.out.println(fd.getConfig().getProductSelections().getSeries());
        }
    }

    输出结果:

    源码:点此下载

  • 相关阅读:
    vue 引用本地图片
    antdVue
    Nest.js —— A progressive Node.js framework
    20184313《网络对抗技术》Exp8 Web综合
    20184313《网络对抗技术》Exp7 网络欺诈防范
    20184313《网络对抗技术》Exp6 MSF应用基础
    20184313《网络对抗技术》Exp5 信息搜集与漏洞扫描
    网页激知序列号之途径(网友提供技术参考)
    【转】Delphi中正则表达式支持中文的写法
    遇到的一个奇怪问题
  • 原文地址:https://www.cnblogs.com/144823836yj/p/14378258.html
Copyright © 2011-2022 走看看