xstream读取xml

xStream可以Java和xml相互转换。下面主要说明xstream读取xml文件(和xstream将Java转化成xml差不多)。本次学习用到的是xstream1.4.7

项目中使用到的xml文件

<config name="personconfig">
    <!-- <add> --> <!-- 使用addImplicitCollection可以不出现 -->
        <address>
            <add>abc;abc</add>
            <zipcode>zip#efg</zipcode>
        </address>
        <address>
            <add>abcfe;123</add>
            <zipcode>zipaf#695</zipcode>
        </address>
    <!-- </add> -->
</config>

保存xml的Java类,其中add存储xml里的所有Address节点信息。

对于不是用注解方式的:

package com.core;

import java.util.ArrayList;
import java.util.List;

public class Person {
    private String name;
    
    /**
     * add名称必须和包含Address的父节点一致,否则数据读取失败(除非使用了addImplicitCollection,则可以不出现<add>
     */
    public List<Address> add = new ArrayList<Address>(); 
    
    public String getName() {
        return name;
    }

    public class Address {
          private String add;   //不一定要给出get/set方法,没有仍然可以从xml读取,这里给出get是因为要读取数据
         private String zipcode;
        public String getAdd() {
            return add;
        }
        public String getZipcode() {
            return zipcode;
        } 
        
    }

}

读取xml主类:

package com.core;

import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.core.Person.Address;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

public class XStreamUtils {
    private String fileName = "xstream.xml";
    
    public XStreamUtils() {
        XStream xstream = new XStream(new DomDriver()); //还可以使用new StaxDriver(),官网推荐xpp3(最快解析xml,但是对于解析程序的配置文件,一般DomDriver和StaxDriver都够了)
//指明类与xml里的element对应关系,如果不指明,则element必须详细到类,如<com.core.Person> xstream.alias("address", Address.class); xstream.alias("config", Person.class); xstream.useAttributeFor(Person.class,"name"); //读取element attribute配置 //the addImplicitCollection method call: it describes which class and which member variable shall assume the behaviour we described. xstream.addImplicitCollection(Person.class, "add"); //此声明可以使得address的父节点不需要出现<add> InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName); Person p = (Person) xstream.fromXML(in); System.out.println(p.add.get(1).getZipcode()); System.out.println(p.getName()); } public static void main(String[] args) { XStreamUtils x = new XStreamUtils(); } }

 注:如果要xml要映射到的Java类里有list的属性(如上面的public List<Address> add),如果address的父节点没有add,而代码里没有使用

addImplicitCollection(Person.class, "add"),则程序会抛出异常。
xstream不要求xml对应的Java类的属性一定要有get和set方法,没有也是可以成功的(估计是用了反射)。

 

2.使用注解:

package com.annotations;

import java.util.ArrayList;
import java.util.List;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import com.thoughtworks.xstream.annotations.XStreamImplicit;

/**
 * 使用Java annotation
 * @author 
 *
 */
@XStreamAlias("config")  //声明在xml中的节点名称
public class Person {
    
    @XStreamAsAttribute  //说明这个值是取自节点attribute
    private String name;

    @XStreamImplicit  //Address节点父节点无需是add
    public List<Address> add = new ArrayList<Address>();

    public String getName() {
        return name;
    }
    
    @XStreamAlias("address")
    public class Address {
        //操作add子节点的内容,将结果放入add中
         @XStreamConverter(value= SplitConverter.class,strings={";"})  
        private List<String> add; // 不一定要给出get/set方法,没有仍然可以从xml读取,这里给出get是因为要读取数据
        
         @XStreamConverter(value= SplitConverter.class,strings={"#"})  
        private List<String> zipcode;
        
         public void toAddressList() {
             System.out.println("address start" + add.size());
             for(String s : add) {
                 System.out.print(s + "\t");
             }
             System.out.println("address end");
         }
        
         public void toZipCodeList() {
             System.out.println("zipcode start" + zipcode.size());
             for(String s : zipcode) {
                 System.out.print(s + "\t");
             }
             System.out.println("zipcode end");
         }

    }

}

SplitConverter实现(Converter可以将xml里某个节点的内容根据需要转换成Java类里面需要的类型,反之亦然。可以使用

 @XStreamConverter(value= SplitConverter.class,strings={";"}来重用converter):
SplitConverte作用:将某个节点的内容按照给定的分割符分割。
package com.annotations;

import java.util.ArrayList;
import java.util.List;

import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

/**
 * 将某个节点的数据根据已给的分割符进行分割
 * @author
 *
 */
public class SplitConverter implements Converter {
    
    private String partionSymbol;
    
    public SplitConverter() {
        super();
    }
    
    public SplitConverter(String str) {
        super();
        this.partionSymbol = str;
    }
    
    /**
     * 判断是否可以convert
     */
    @Override
    public boolean canConvert(Class arg0) {
        // TODO Auto-generated method stub
        return true;
    }

    /**
     * 写xml时,Java属性特殊处理
     */
    @Override
    public void marshal(Object arg0, HierarchicalStreamWriter arg1,
            MarshallingContext arg2) {
        // TODO Auto-generated method stub

    }

    /**
     * 读取xml数据时对某个节点的数据操作
     */
    @Override
    public Object unmarshal(HierarchicalStreamReader reader,
            UnmarshallingContext arg1) {
        // TODO Auto-generated method stub
        List<String> list = null;
        String content = reader.getValue();
        String[] arr = content.split(this.partionSymbol);
        if(null != arr) {
            list = new ArrayList<String>(arr.length);
            for(String s : arr) {
                list.add(s);
            }
        }
        return list;
    }

}

注解 Main类:

package com.annotations;

import java.io.InputStream;

import com.annotations.Person.Address;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

public class AnnotationMain {

private String fileName = "xstream.xml";
    
    public AnnotationMain() {
        XStream xstream = new XStream(new DomDriver());
        //说明注解了哪些些类
        xstream.processAnnotations(Person.class);
        xstream.processAnnotations(Address.class);
        InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
        Person p = (Person) xstream.fromXML(in);
        p.add.get(0).toAddressList();
        p.add.get(1).toZipCodeList();
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        AnnotationMain a = new AnnotationMain();
    }

}

 

 附:

Xstream常用注解: 
@XStreamAlias("message") :

  别名注解  

作用目标: 类,字段  

@XStreamImplicit

隐式集合 

@XStreamImplicit(itemFieldName="subElementName")  
作用目标:

集合字段  

@XStreamConverter(SingleValueCalendarConverter.class)    //不传入参数的

注入转换器  
作用目标: 对象  

@XStreamAsAttribute 转换成属性  
作用目标: 字段  

@XStreamOmitField 忽略字段  
作用目标: 字段  

 

此次学习时的测试项目在:http://pan.baidu.com/s/1tjzNC

 

 

 

 

 

 

转载于:https://www.cnblogs.com/visoncheng/p/3712801.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值