• Java解析和生成XML


    1、Jaxb处理java对象和xml之间转换常用的annotation有:
    1. @XmlType
    1. @XmlElement
    1. @XmlRootElement
    1. @XmlAttribute
    1. @XmlAccessorType
    1. @XmlAccessorOrder
    1. @XmlTransient
    1. @XmlJavaTypeAdapter
    2、常用annotation使用说明
    @XmlType
      @XmlType用在class类的注解,常与@XmlRootElement,@XmlAccessorType一起使用。它有三个属性:name、propOrder、namespace,经常使用的只有前两个属性。如:
      
    @XmlType(name = "basicStruct", propOrder = {    
        "intValue",    
        "stringArray",    
        "stringValue")
    在使用@XmlType的propOrder 属性时,必须列出JavaBean对象中的所有属性,否则会报错。
    • @XmlElement
    @XmlElement将Java对象的属性映射为xml的节点,在使用@XmlElement时,可通过name属性改变java对象属性在xml中显示的名称。如:
      @XmlElement(name="Address")  
      private String yourAddress;
     
    @XmlRootElement
    • @XmlRootElement用于类级别的注解,对应xml的跟元素,常与 @XmlType 和 @XmlAccessorType一起使用。如:
      @XmlType
      @XmlAccessorType(XmlAccessType.FIELD)
      @XmlRootElement
      public class Address {}
     
    @XmlAttribute
    @XmlAttribute用于把java对象的属性映射为xml的属性,并可通过name属性为生成的xml属性指定别名。如:
      @XmlAttribute(name="Country")
      private String state;
     
    @XmlAccessorType
    @XmlAccessorType用于指定由java对象生成xml文件时对java对象属性的访问方式。常与@XmlRootElement、@XmlType一起使用。它的属性值是XmlAccessType的4个枚举值,分 别为:
      XmlAccessType.FIELD:java对象中的所有成员变量
      XmlAccessType.PROPERTY:java对象中所有通过getter/setter方式访问的成员变量
      XmlAccessType.PUBLIC_MEMBER:java对象中所有的public访问权限的成员变量和通过getter/setter方式访问的成员变量
      XmlAccessType.NONE:java对象的所有属性都不映射为xml的元素
      注意:@XmlAccessorType的默认访问级别是XmlAccessType.PUBLIC_MEMBER,因此,如果java对象中的private成员变量设置了public权限的getter/setter方法,就不要在   private变量上使用@XmlElement和@XmlAttribute注解,否则在由java对象生成xml时会报同一个属性在java类里存在两次的错误。同理,如果@XmlAccessorType的访问权限   为XmlAccessType.NONE,如果在java的成员变量上使用了@XmlElement或@XmlAttribute注解,这些成员变量依然可以映射到xml文件。
     
    @XmlAccessorOrder
    @XmlAccessorOrder用于对java对象生成的xml元素进行排序。它有两个属性值:
      AccessorOrder.ALPHABETICAL:对生成的xml元素按字母书序排序
      XmlAccessOrder.UNDEFINED:不排序
     
    @XmlTransient
    @XmlTransient用于标示在由java对象映射xml时,忽略此属性。即,在生成的xml文件中不出现此元素。
     
    @XmlJavaTypeAdapter
    @XmlJavaTypeAdapter常用在转换比较复杂的对象时,如map类型或者格式化日期等。使用此注解时,需要自己写一个adapter类继承XmlAdapter抽象类,并实现里面的方法。
      @XmlJavaTypeAdapter(value=xxx.class),value为自己定义的adapter类
      XmlAdapter如下:
    public abstract class XmlAdapter<ValueType,BoundType> {
        // Do-nothing constructor for the derived classes.
        protected XmlAdapter() {}
        // Convert a value type to a bound type.
        public abstract BoundType unmarshal(ValueType v);
        // Convert a bound type to a value type.
        public abstract ValueType marshal(BoundType v);
     }
    3、示例
    Shop.java
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.math.BigDecimal;
    import java.util.Date;
    import java.util.HashSet;
    import java.util.Set;
    
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.Marshaller;
    import javax.xml.bind.Unmarshaller;
    import javax.xml.bind.annotation.XmlAccessType;
    import javax.xml.bind.annotation.XmlAccessorOrder;
    import javax.xml.bind.annotation.XmlAccessOrder;
    import javax.xml.bind.annotation.XmlAccessorType;
    import javax.xml.bind.annotation.XmlAttribute;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlElementWrapper;
    import javax.xml.bind.annotation.XmlRootElement;
    import javax.xml.bind.annotation.XmlType;
    
    //设置生成的xml的根节点的名称
    @XmlRootElement(name = "shop")
    //设置根据字段还是方法生成
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)  
    @XmlType(name = "shop", propOrder = { "name", "number", "describer", "address","orders" })  
    public class Shop {
        
        public static void main(String[] args) {
            Set<Order> orders = new HashSet<Order>();  
            
            Address address1 = new Address("China", "ShangHai", "ShangHai", "Huang", "200000");  
            Customer customer1 = new Customer("Jim", "male", "13699990000", address1);  
            Order order1 = new Order("Mart", "LH59900", new Date(), new BigDecimal(60), 1);  
            order1.setCustomer(customer1);
              
            Address address2 = new Address("China", "JiangSu", "NanJing", "ZhongYangLu", "210000");  
            Customer customer2 = new Customer("David", "male", "13699991000", address2);  
            Order order2 = new Order("Mart", "LH59800", new Date(), new BigDecimal(80), 1);  
            order2.setCustomer(customer2);  
              
            orders.add(order1);  
            orders.add(order2);  
              
            Address address3 = new Address("China", "ZheJiang", "HangZhou", "XiHuRoad", "310000");  
            Shop shop = new Shop("CHMart", "100000", "EveryThing",address3);  
            shop.setOrders(orders);  
              
            FileWriter writer = null;  
            try {  
                JAXBContext context = JAXBContext.newInstance(Shop.class);  
                Marshaller marshal = context.createMarshaller();  
                marshal.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);  
                marshal.marshal(shop, System.out);  
                  
                writer = new FileWriter("shop.xml");  
                marshal.marshal(shop, writer); 
                
                Unmarshaller unmarshal = context.createUnmarshaller();  
                FileReader reader = new FileReader("shop.xml") ;  
                Shop shop1 = (Shop)unmarshal.unmarshal(reader);  
                  
                Set<Order> orders1 = shop1.getOrders();  
                for(Order order : orders1){  
                    System.out.println("***************************");  
                    System.out.println(order.getOrderNumber());  
                    System.out.println(order.getCustomer().getName());  
                    System.out.println("***************************");  
                }
                
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
            
            
            
        }
        
        @XmlAttribute  
        private String name;  
      
        // @XmlElement  
        private String number;  
      
        @XmlElement  
        private String describer;  
      
        @XmlElementWrapper(name = "orders")  
        @XmlElement(name = "order")  
        private Set<Order> orders;  
      
        @XmlElement  
        private Address address;  
      
        public Shop() {  
        }  
      
        public Shop(String name, String number, String describer, Address address) {  
            this.name = name;  
            this.number = number;  
            this.describer = describer;  
            this.address = address;  
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getNumber() {
            return number;
        }
    
        public void setNumber(String number) {
            this.number = number;
        }
    
        public String getDescriber() {
            return describer;
        }
    
        public void setDescriber(String describer) {
            this.describer = describer;
        }
    
        public Set<Order> getOrders() {
            return orders;
        }
    
        public void setOrders(Set<Order> orders) {
            this.orders = orders;
        }
    
        public Address getAddress() {
            return address;
        }
    
        public void setAddress(Address address) {
            this.address = address;
        }  
    }

    Order.java

    import java.math.BigDecimal;
    import java.util.Date;
    
    import javax.xml.bind.annotation.XmlAccessorType;
    import javax.xml.bind.annotation.XmlAccessType;
    import javax.xml.bind.annotation.XmlAttribute;
    import javax.xml.bind.annotation.XmlRootElement;
    import javax.xml.bind.annotation.XmlType;
    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
    
    @XmlType(name="order",propOrder={"shopName","orderNumber","price","amount","purDate","customer"})  
    @XmlAccessorType(XmlAccessType.FIELD)  
    @XmlRootElement  
    public class Order {
        private String shopName;  
          
        @XmlAttribute  
        private String orderNumber;  
      
        @XmlJavaTypeAdapter(value=DateAdapter.class)  
        private Date purDate;  
      
        private BigDecimal price;  
      
        private int amount;  
      
        private Customer customer;  
      
        public Order() {  
        }  
      
        public Order(String shopName, String orderNumber, Date purDate,  
                BigDecimal price, int amount) {  
            this.shopName = shopName;  
            this.orderNumber = orderNumber;  
            this.purDate = purDate;  
            this.price = price;  
            this.amount = amount;  
        }
    
        public String getShopName() {
            return shopName;
        }
    
        public void setShopName(String shopName) {
            this.shopName = shopName;
        }
    
        public String getOrderNumber() {
            return orderNumber;
        }
    
        public void setOrderNumber(String orderNumber) {
            this.orderNumber = orderNumber;
        }
    
        public Date getPurDate() {
            return purDate;
        }
    
        public void setPurDate(Date purDate) {
            this.purDate = purDate;
        }
    
        public BigDecimal getPrice() {
            return price;
        }
    
        public void setPrice(BigDecimal price) {
            this.price = price;
        }
    
        public int getAmount() {
            return amount;
        }
    
        public void setAmount(int amount) {
            this.amount = amount;
        }
    
        public Customer getCustomer() {
            return customer;
        }
    
        public void setCustomer(Customer customer) {
            this.customer = customer;
        }  
        
    }

    Customer.java

    import java.util.Set;
    
    import javax.xml.bind.annotation.XmlAccessorType;
    import javax.xml.bind.annotation.XmlAccessType;
    import javax.xml.bind.annotation.XmlAttribute;
    import javax.xml.bind.annotation.XmlRootElement;
    import javax.xml.bind.annotation.XmlType;
    
    @XmlType  
    @XmlAccessorType(XmlAccessType.FIELD)  
    @XmlRootElement 
    public class Customer {
        @XmlAttribute  
        private String name;  
      
        private String gender;  
      
        private String phoneNo;  
      
        private Address address;  
      
        private Set<Order> orders;  
      
        public Customer() {  
        }  
      
        public Customer(String name, String gender, String phoneNo, Address address) {  
            this.name = name;  
            this.gender = gender;  
            this.phoneNo = phoneNo;  
            this.address = address;  
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getGender() {
            return gender;
        }
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    
        public String getPhoneNo() {
            return phoneNo;
        }
    
        public void setPhoneNo(String phoneNo) {
            this.phoneNo = phoneNo;
        }
    
        public Address getAddress() {
            return address;
        }
    
        public void setAddress(Address address) {
            this.address = address;
        }
    
        public Set<Order> getOrders() {
            return orders;
        }
    
        public void setOrders(Set<Order> orders) {
            this.orders = orders;
        }  
        
    }

    Address.java

    import javax.xml.bind.annotation.XmlAccessorOrder;
    import javax.xml.bind.annotation.XmlAccessOrder;
    import javax.xml.bind.annotation.XmlAccessorType;
    import javax.xml.bind.annotation.XmlAccessType;
    import javax.xml.bind.annotation.XmlAttribute;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;
    import javax.xml.bind.annotation.XmlType;
    
    @XmlType(propOrder = { "state", "province", "city", "street", "zip" })
    @XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
    @XmlAccessorType(XmlAccessType.NONE)
    @XmlRootElement
    public class Address {
        @XmlAttribute
        private String state;
    
        @XmlElement
        private String province;
    
        @XmlElement
        private String city;
    
        @XmlElement
        private String street;
    
        @XmlElement
        private String zip;
    
        public Address() {
            super();
        }
    
        public Address(String state, String province, String city, String street,
                String zip) {
            super();
            this.state = state;
            this.province = province;
            this.city = city;
            this.street = street;
            this.zip = zip;
        }
    
        public String getState() {
            return state;
        }
    
        public void setState(String state) {
            this.state = state;
        }
    
        public String getProvince() {
            return province;
        }
    
        public void setProvince(String province) {
            this.province = province;
        }
    
        public String getCity() {
            return city;
        }
    
        public void setCity(String city) {
            this.city = city;
        }
    
        public String getStreet() {
            return street;
        }
    
        public void setStreet(String street) {
            this.street = street;
        }
    
        public String getZip() {
            return zip;
        }
    
        public void setZip(String zip) {
            this.zip = zip;
        }
    
    }

    输出:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <shop name="CHMart">
        <number>100000</number>
        <describer>EveryThing</describer>
        <address state="China">
            <province>ZheJiang</province>
            <city>HangZhou</city>
            <street>XiHuRoad</street>
            <zip>310000</zip>
        </address>
        <orders>
            <order orderNumber="LH59900">
                <shopName>Mart</shopName>
                <price>60</price>
                <amount>1</amount>
                <purDate>2016-11-23 14:51:40</purDate>
                <customer name="Jim">
                    <gender>male</gender>
                    <phoneNo>13699990000</phoneNo>
                    <address state="China">
                        <province>ShangHai</province>
                        <city>ShangHai</city>
                        <street>Huang</street>
                        <zip>200000</zip>
                    </address>
                </customer>
            </order>
            <order orderNumber="LH59800">
                <shopName>Mart</shopName>
                <price>80</price>
                <amount>1</amount>
                <purDate>2016-11-23 14:51:40</purDate>
                <customer name="David">
                    <gender>male</gender>
                    <phoneNo>13699991000</phoneNo>
                    <address state="China">
                        <province>JiangSu</province>
                        <city>NanJing</city>
                        <street>ZhongYangLu</street>
                        <zip>210000</zip>
                    </address>
                </customer>
            </order>
        </orders>
    </shop>
    ***************************
    LH59900
    Jim
    ***************************
    ***************************
    LH59800
    David
    **************************

    工具类JaxbUtil.java:

    import java.io.StringReader;
    import java.io.StringWriter;
    import java.util.Collection;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.ConcurrentMap;
    
    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.lang3.Validate;
    
    import com.thinkgem.jeesite.common.utils.Exceptions;
    import com.thinkgem.jeesite.common.utils.Reflections;
    import com.thinkgem.jeesite.common.utils.StringUtils;
    /**
     * 使用Jaxb2.0实现XML<->Java Object的Mapper.
     * 在创建时需要设定所有需要序列化的Root对象的Class.
     * 特别支持Root对象是Collection的情形.
     */
    public class JaxbUtil {
            private static ConcurrentMap<Class, JAXBContext> jaxbContexts = new ConcurrentHashMap<Class, JAXBContext>();
            /**
         * Java Object->Xml without encoding.
         */
        @SuppressWarnings("rawtypes")
        public static String toXml(Object root) {
            Class clazz = Reflections.getUserClass(root);
            return toXml(root, clazz, null);
        }
    
        /**
         * Java Object->Xml with encoding.
         */
        @SuppressWarnings("rawtypes")
        public static String toXml(Object root, String encoding) {
            Class clazz = Reflections.getUserClass(root);
            return toXml(root, clazz, encoding);
        }
    
        /**
         * Java Object->Xml with encoding.
         */
        @SuppressWarnings("rawtypes")
        public static String toXml(Object root, Class clazz, String encoding) {
            try {
                StringWriter writer = new StringWriter();
                createMarshaller(clazz, encoding).marshal(root, writer);
                return writer.toString();
            } catch (JAXBException e) {
                throw Exceptions.unchecked(e);
            }
        }
    
        /**
         * Java Collection->Xml without encoding, 特别支持Root Element是Collection的情形.
         */
        @SuppressWarnings("rawtypes")
        public static String toXml(Collection<?> root, String rootName, Class clazz) {
            return toXml(root, rootName, clazz, null);
        }
    
        /**
         * Java Collection->Xml with encoding, 特别支持Root Element是Collection的情形.
         */
        @SuppressWarnings("rawtypes")
        public static String toXml(Collection<?> root, String rootName, Class clazz, String encoding) {
            try {
                CollectionWrapper wrapper = new CollectionWrapper();
                wrapper.collection = root;
    
                JAXBElement<CollectionWrapper> wrapperElement = new JAXBElement<CollectionWrapper>(new QName(rootName),
                        CollectionWrapper.class, wrapper);
    
                StringWriter writer = new StringWriter();
                createMarshaller(clazz, encoding).marshal(wrapperElement, writer);
    
                return writer.toString();
            } catch (JAXBException e) {
                throw Exceptions.unchecked(e);
            }
        }
    
        /**
         * Xml->Java Object.
         */
        @SuppressWarnings("unchecked")
        public static <T> T fromXml(String xml, Class<T> clazz) {
            try {
                StringReader reader = new StringReader(xml);
                return (T) createUnmarshaller(clazz).unmarshal(reader);
            } catch (JAXBException e) {
                throw Exceptions.unchecked(e);
            }
        }
    
        /**
         * 创建Marshaller并设定encoding(可为null).
         * 线程不安全,需要每次创建或pooling。
         */
        @SuppressWarnings("rawtypes")
        public static Marshaller createMarshaller(Class clazz, String encoding) {
            try {
                JAXBContext jaxbContext = getJaxbContext(clazz);
    
                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 Exceptions.unchecked(e);
            }
        }
    
        /**
         * 创建UnMarshaller.
         * 线程不安全,需要每次创建或pooling。
         */
        @SuppressWarnings("rawtypes")
        public static Unmarshaller createUnmarshaller(Class clazz) {
            try {
                JAXBContext jaxbContext = getJaxbContext(clazz);
                return jaxbContext.createUnmarshaller();
            } catch (JAXBException e) {
                throw Exceptions.unchecked(e);
            }
        }
    
        @SuppressWarnings("rawtypes")
        protected static JAXBContext getJaxbContext(Class clazz) {
            Validate.notNull(clazz, "'clazz' must not be null");
            JAXBContext jaxbContext = jaxbContexts.get(clazz);
            if (jaxbContext == null) {
                try {
                    jaxbContext = JAXBContext.newInstance(clazz, CollectionWrapper.class);
                    jaxbContexts.putIfAbsent(clazz, jaxbContext);
                } catch (JAXBException ex) {
                    throw new RuntimeException("Could not instantiate JAXBContext for class [" + clazz + "]: "
                            + ex.getMessage(), ex);
                }
            }
            return jaxbContext;
        }
    
        /**
         * 封装Root Element 是 Collection的情况.
         */
        public static class CollectionWrapper {
    
            @XmlAnyElement
            protected Collection<?> collection;
        }
    }

    测试:

    String s = JaxbUtil.toXml(shop);
    System.out.println(s);

    输出:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <shop name="CHMart">
        <number>100000</number>
        <describer>EveryThing</describer>
        <address state="China">
            <province>ZheJiang</province>
            <city>HangZhou</city>
            <street>XiHuRoad</street>
            <zip>310000</zip>
        </address>
        <orders>
            <order orderNumber="LH59800">
                <shopName>Mart</shopName>
                <price>80</price>
                <amount>1</amount>
                <purDate>2016-11-23 14:54:39</purDate>
                <customer name="David">
                    <gender>male</gender>
                    <phoneNo>13699991000</phoneNo>
                    <address state="China">
                        <province>JiangSu</province>
                        <city>NanJing</city>
                        <street>ZhongYangLu</street>
                        <zip>210000</zip>
                    </address>
                </customer>
            </order>
            <order orderNumber="LH59900">
                <shopName>Mart</shopName>
                <price>60</price>
                <amount>1</amount>
                <purDate>2016-11-23 14:54:39</purDate>
                <customer name="Jim">
                    <gender>male</gender>
                    <phoneNo>13699990000</phoneNo>
                    <address state="China">
                        <province>ShangHai</province>
                        <city>ShangHai</city>
                        <street>Huang</street>
                        <zip>200000</zip>
                    </address>
                </customer>
            </order>
        </orders>
    </shop>
  • 相关阅读:
    .NET Core使用swagger进行API接口文档管理
    此用户不允许自调用
    How to get raw request body in ASP.NET?
    支付宝app对接的坑
    PowerDesigner code、name显示设置 及 同时显示办法
    core里使用log4net
    core的微服务相关
    SQLPrompt 安装后sql上看不到菜单
    IIS配置支持跨域请求
    根据select出来的数据进行update
  • 原文地址:https://www.cnblogs.com/ycyoes/p/6093681.html
Copyright © 2020-2023  润新知