美文网首页Java 技术贴
Java获取并解析XML(JavaBean和XML的转化)

Java获取并解析XML(JavaBean和XML的转化)

作者: Steven0T | 来源:发表于2019-12-06 17:34 被阅读0次

    最近遇到一个问题,需要从一个url获取xml文档并解析,google了很多方法,大多数都
    是获取到XML然后循环遍历拿到数据,但是感觉很麻烦,并且感觉当数据量比较大的时候效率也不怎么
    高,后面研究了下,发现JAXB这个好东西,可以实现JavaBean和XML节点元素的互相转换,故此总结一
    下:

    1、相关链接

    2、准备工作

    需要安装JAXB和dom4j,如果用的Maven,可以访问上面的url,并搜索JAXB和dom4j,选择需要的版本
    ,复制下面的代码配置到自己的项目中:

    3、获取并解析

    先看一下返回的XML格式

    <HotelGeos>
        <HotelGeoList>
            <HotelGeo CityCode="0101" CityName="北京市" Country="中国" ProvinceId="0100" ProvinceNam
                      e="北京市">
                <CommericalLocations>
                    <Location Id="010103" Name="天安门/王府井商业区"/>
                    <Location Id="010119" Name="前门/大栅栏"/>
                </CommericalLocations>
                <Districts>
                    <Location Id="0001" Name="浦东新区"/>
                    <Location Id="0028" Name="闵行区"/>
                </Districts>
                <LandmarkLocations>
                    <Location Id="60000283" Name="上海虹桥站"/>
                    <Location Id="60000282" Name="上海站"/>
                </LandmarkLocations>
            </HotelGeo>
        </HotelGeoList>
    </HotelGeos>
    
    解析
    public static void main(String[] args) {
           //获取XML
           SAXReader reader = new SAXReader();
           org.dom4j.Document document = reader.read(new URL("http://api.************************                */v2.0/hotel/geo_cn.xml")));
           String documentStr = document.asXML();
           //将xml字符串转换为java对象
           JaxbUtil resultBinder = new JaxbUtil(HotelGeos.class, JaxbUtil.CollectionWrapper.class);
           HotelGeos hotelObj = resultBinder.fromXml(documentStr);
           //将java对象转换为XML字符串
           HotelGeos hotelGeos=new HotelGeos();
           List<HotelGeo> hotelGeoList=new ArrayList<>();
           HotelGeo hotelGeo =new HotelGeo();
           hotelGeo.setCityCode("0101");
           hotelGeo.setCityName("北京市");
           hotelGeo.setCountry("中国");
           hotelGeo.setProvinceId("0100");
           hotelGeo.setProvinceName("北京市");
           //其他层级的这里就不一一赋值了
           hotelGeoList.add(hotelGeo);
           hotelGeos.setHotelGeoList(hotelGeoList);
           JaxbUtil requestBinder = new JaxbUtil(HotelGeos.class, CollectionWrapper.class);
           String retXml = requestBinder.toXml(hotelGeos, "utf-8");
           System.out.println("xml:"+retXml);
       }
    
    相关类之HotelGeos
    package com .*****.geoData.items;
       import lombok.Data;
       import javax.xml.bind.annotation .*;
       import java.util.List;
    
       /**
        * Created by IntelliJ IDEA.
        * User: Steven
        * Date: 2019/12/05
        * Time: 13:36
        */
       @Data
       @XmlRootElement(name = "HotelGeos")
       public class HotelGeos {
           @XmlElementWrapper(name = "HotelGeoList")
           @XmlElement(name = "HotelGeo")
           private List<HotelGeo> HotelGeoList;
       }
    
    HotelGeo
    package com.***.geoData.items;
       import lombok.Data;
       import org.codehaus.jackson.map.annotate.JsonSerialize;
       import javax.xml.bind.annotation.XmlAttribute;
       import javax.xml.bind.annotation.XmlElement;
       import javax.xml.bind.annotation.XmlElementWrapper;
       import java.io.Serializable;
       import java.util.List;
       /**
        * Created by IntelliJ IDEA.
        * User: Steven
        * Date: 2019/12/06
        * Time: 13:38
        */
       @Data
       @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
       public class HotelGeo implements Serializable {
           @XmlAttribute(name = "CityCode")
           private String CityCode;
           @XmlAttribute(name = "CityName")
           private String CityName;
           @XmlAttribute(name = "Country")
           private String Country;
           @XmlAttribute(name = "ProvinceId")
           private String ProvinceId;
           @XmlAttribute(name = "ProvinceName")
           private String ProvinceName;
           @XmlElementWrapper(name = "CommericalLocations")
           @XmlElement(name = "Location") //这里需要格外注意,层级很容易写错
           private List<Location> CommericalLocations;
           @XmlElementWrapper(name = "Districts")
           @XmlElement(name = "Location")
           private List<Location> Districts;
           @XmlElementWrapper(name = "LandmarkLocations")
           @XmlElement(name = "Location")
           private List<Location> LandmarkLocations;
       }
    
    Location
        package com.*****.geoData.items;
        import lombok.Data;
        import org.codehaus.jackson.map.annotate.JsonSerialize;
        import javax.xml.bind.annotation.XmlAttribute;
        import java.io.Serializable;
        /**
         * Created by IntelliJ IDEA.
         * User: Steven
         * Date: 2019/12/06
         * Time: 13:53
         */
        @Data
        @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
        public class Location implements Serializable {
            @XmlAttribute(name = "Id")
            private String Id;
            @XmlAttribute(name = "Name")
            private String Name;
        }
    
    JaxbUtil工具类
    
    package com.*****.utils;
    import java.io.StringReader;
    import java.io.StringWriter;
    import java.util.Collection;
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.JAXBElement;
    import javax.xml.bind.JAXBException;
    import javax.xml.bind.Marshaller;
    import javax.xml.bind.Unmarshaller;
    import javax.xml.bind.annotation.XmlAnyElement;
    import javax.xml.namespace.QName;
    import org.apache.commons.lang.StringUtils;
    /**
     * 使用Jaxb2.0实现XML<->Java Object的Binder.
     *
     * 特别支持Root对象是List的情形.
     *
     * @author
     */public class JaxbUtil {
        // 多线程安全的Context.
        private JAXBContext jaxbContext;
        /**
         * @param types
         * 所有需要序列化的Root对象的类型.
         */
        public JaxbUtil(Class<?>... types) {
            try {
                jaxbContext = JAXBContext.newInstance(types);
            } catch (JAXBException e) {
                throw new RuntimeException(e);
            }
        }
        /**
         * Java Object->Xml.
         */
        public String toXml(Object root, String encoding) {
            try {
                StringWriter writer = new StringWriter();
                createMarshaller(encoding).marshal(root, writer);
                return writer.toString();
            } catch (JAXBException e) {
                throw new RuntimeException(e);
            }
        }
        /**
         * Java Object->Xml, 特别支持对Root Element是Collection的情形.
         */
        @SuppressWarnings("unchecked")
        public String toXml(Collection root, String rootName, String encoding) {
            try {
                CollectionWrapper wrapper = new CollectionWrapper();
                wrapper.collection = root;
                JAXBElement<CollectionWrapper> wrapperElement = new JAXBElement<CollectionWrap
                per>(
                        new QName(rootName), CollectionWrapper.class, wrapper);
                StringWriter writer = new StringWriter();
                createMarshaller(encoding).marshal(wrapperElement, writer);
                return writer.toString();
            } catch (JAXBException e) {
                throw new RuntimeException(e);
            }
        }/**
         * Xml->Java Object.
         */
        @SuppressWarnings("unchecked")
        public <T> T fromXml(String xml) {
            try {
                StringReader reader = new StringReader(xml);
                return (T) createUnmarshaller().unmarshal(reader);
            } catch (JAXBException e) {
                throw new RuntimeException(e);
            }
        }
        /**
         * Xml->Java Object, 支持大小写敏感或不敏感.
         */
        @SuppressWarnings("unchecked")
        public <T> T fromXml(String xml, boolean caseSensitive) {
            try {
                String fromXml = xml;
                if (!caseSensitive)
                    fromXml = xml.toLowerCase();
                StringReader reader = new StringReader(fromXml);
                return (T) createUnmarshaller().unmarshal(reader);
            } catch (JAXBException e) {
                throw new RuntimeException(e);
            }
        }
        /**
         * 创建Marshaller, 设定encoding(可为Null).
         */
        public Marshaller createMarshaller(String encoding) {
            try {
                Marshaller marshaller = jaxbContext.createMarshaller();
                marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
                if (StringUtils.isNotBlank(encoding)) {
                    marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
                }
                return marshaller;
            } catch (JAXBException e) {
                throw new RuntimeException(e);
            }
        }
    /**
     * 创建UnMarshaller
    */
     public Unmarshaller createUnmarshaller() {
            try {
                return jaxbContext.createUnmarshaller();
            } catch (JAXBException e) {
                throw new RuntimeException(e);
            }
        }
     
      /**
      * 封装Root Element 是 Collection的情况.
      */
    
        public static class CollectionWrapper {
     
            @SuppressWarnings("unchecked")
     
            @XmlAnyElement
     
            protected Collection collection;
     
        }
     
    }
    

    相关文章

      网友评论

        本文标题:Java获取并解析XML(JavaBean和XML的转化)

        本文链接:https://www.haomeiwen.com/subject/roudgctx.html