zoukankan      html  css  js  c++  java
  • 使用xStream进行java object<-->xml之间的转换

    1. 完成java object和xml之间的转换方法有多种。一种是利用xtream,一种是利用hibernate的第三方工具。
    2. xtream非常简单,不需要生成dtd,无用配置,不需要生成辅助类,虽然功能相对其他的同类工具要简单,但是基本上都能满足需要。
    3. hibernate有第三方工具,可以方便的在xml/obj/db之间转换。 
    4. xtream+xpp也是一个很好的选择
    5. public static void write() {   
    6.     XStream sm = new XStream();   
    7.     mytest t = new mytest();   
    8.     t.setName("moogle");   
    9.     t.setXb("男");   
    10.     try {   
    11.     FileOutputStream ops = new FileOutputStream(new File("C:\111.xml"));   
    12.     sm.toXML(t, ops);   
    13.     ops.close();   
    14.     } catch (Exception e) {   
    15.         e.printStackTrace();   
    16.     }   
    17. }      
    18. public static void read() {   
    19.     XStream sm = new XStream(new DomDriver());   
    20.     try {   
    21.         FileInputStream ops = new FileInputStream(new File("C:\111.xml"));   
    22.         mytest t = (mytest)sm.fromXML(ops);   
    23.         System.out.println(t.getName());   
    24.         ops.close();   
    25.         } catch (Exception e) {   
    26.             e.printStackTrace();   
    27.         }          

    生成的XML文件内容:

    xml 代码
    1. <mytest>  
    2.   <name>asd</name>  
    3.   <xb>男</xb>  
    4. </mytest>  


    问题:
    1.生成的xml文档没有<!---->

    2.如果生成的文档中含有中文,比如上文代码中setXb("男")
    在读取的时候会报

    [Fatal Error] :4:7: Invalid byte 2 of 2-byte UTF-8 sequence.

    解决办法

      1. 加入xpp3_min-1.1.3.4.O.jar(包含在xStream压缩包中) 
        将 
        XStream sm = new XStream(new DomDriver());

        XStream sm = new XStream();

    不需要生成dtd,无用配置,不需要生成辅助类,速度快。这就是xstream+xpp超强黄金组合。
    xstream大家都知道啦,XML Pull Parser是一种高速的 解析xml文件的方式,速度要比传统方式快很多(发现pull式解析现在比较流行了)。下面我给出多种使用方法的例子。


    1.最简单的使用方法
    因为这个太简单,所以我从moogle的blog http://moogle.javaeye.com/blog/34661取下面的例子
       1.  public static void write() {   
       2.     XStream sm = new XStream();   
       3.     mytest t = new mytest();   
       4.     t.setName("moogle");   
       5.     t.setXb("男");   
       6.     try {   
       7.     FileOutputStream ops = new FileOutputStream(new File("C://111.xml"));   
       8.     sm.toXML(t, ops);   
       9.     ops.close();   
      10.     } catch (Exception e) {   
      11.         e.printStackTrace();   
      12.     }   
      13. }      
      14. public static void read() {   
      15.     XStream sm = new XStream(new DomDriver());   
      16.     try {   
      17.         FileInputStream ops = new FileInputStream(new File("C://111.xml"));   
      18.         mytest t = (mytest)sm.fromXML(ops);   
      19.         System.out.println(t.getName());   
      20.         ops.close();   
      21.         } catch (Exception e) {   
      22.             e.printStackTrace();   
      23.         }          
      24. }

    生成 XML是
    # <mytest>  
    #   <name>asd</name>  
    #   <xb>男</xb>


     
    2.中等方法(需要1.2版以上才有这个功能)
    XStream stream = new XStream();
    stream.alias("schema", SchemaObject.class);
    stream.useAttributeFor("url", String.class);
    stream.useAttributeFor("jdbcDriverClass", String.class);
    stream.useAttributeFor("user", String.class);
    stream.useAttributeFor("password", String.class);
    FileOutputStream s = new FileOutputStream(file);
    stream.toXML(theObject, s);
    s.close();
    alias和useAttributeFor是用作把 <com.hongsoft.model.SchemaObject>修改为<schema>


    3.高级方法
    XStream stream = new XStream();
    stream.registerConverter(new SchemaXMLConvertor());
    stream.alias("schema", SchemaObject.class);
    FileInputStream s = new FileInputStream(file);
    object = (SchemaObject) stream.fromXML(s);
    s.close();


    registerConverter可以实现把任何schema的XML和object互相转换,这个其实已经否定了很多朋友说的
    “xstream+xpp”功能不强的说法。SchemaXMLConvertor示例如下:


    public void marshal(Object arg0, HierarchicalStreamWriter writer,
                MarshallingContext arg2) {
        SchemaObject schema=(SchemaObject)arg0;        
        writer.startNode(SchemaObject.TABLE);
        writer.addAttribute(SchemaObject.TABLE_NAME, iTable.getName());
        //line            
        List<SchemaObject.TableObject.LineObject> lines=iTable.getLines();
        for(int j=0;j<lines.size();j++)
        {
            SchemaObject.TableObject.LineObject jLine=lines.get(j);
            writer.startNode(SchemaObject.LINE);
            //column
            Map<String,String> columns=jLine.getColumns();
            Iterator ite=columns.keySet().iterator();
            while(ite.hasNext())
            {
                String columnName=ite.next().toString();
                writer.addAttribute(columnName, columns.get(columnName));
            }
            writer.endNode();
            }
            writer.endNode();
            writer.underlyingWriter();
        }

    public Object unmarshal(HierarchicalStreamReader reader,
                UnmarshallingContext arg1) {
        SchemaObject schema=new SchemaObject();
        schema.setJdbcDriverClass(reader.getAttribute(SchemaObject.JDBC_DRIVER_CLASS));
        schema.setUrl(reader.getAttribute(SchemaObject.URL));
        schema.setUser(reader.getAttribute(SchemaObject.USER));
        schema.setPassword(reader.getAttribute(SchemaObject.PASSWORD));
        List<TableObject> tables = new ArrayList<TableObject>();
            while(reader.hasMoreChildren()) {
                reader.moveDown();
                SchemaObject.TableObject table=new SchemaObject().new TableObject();
                table.setName(reader.getAttribute(SchemaObject.TABLE_NAME));
                tables.add(table);
                reader.moveUp();
            }
            schema.setTables(tables);        
            return schema;
    }
    public boolean canConvert(Class arg0) {
        return arg0.equals(SchemaObject.class);
    }

    说明:
    1、XStream不要求Java类的属性必须有getter、setter方法,因此省略。
     
    2、设置java成员属性别名
            xStream.aliasField("Investor-List",MainBody.class,"investorList");
            outXML(3,xStream,mainBody);
    运行结果会产生:
      <Investor-List>
     
    3、将java成员映射为xml元素的一个属性
     
            //将name成员作为属性添加到Investor对应xml节点里       
            xStream.useAttributeFor(Investor.class,"name");
     
    运行结果会产生:
                <Investor name="hahhah">
     
     
    下面这两句是相关联的:
            xStream.aliasAttribute(Investor.class,"name","GDXM");
            xStream.useAttributeFor(Investor.class,"name");
            意思是先为java成员定义个别名,然后在将别名应用于xml属性上。
     
    运行结果会产生:
                <Investor GDXM="hahhah">
     
    这些问题虽然解决了,但又发现了新的问题:xml转java时,当java中没有定义xml元素节点时,这时候会抛出异常。也许通过XStream本身的API可以解决,也许是XStream本身所不能处理的问题,时间有限,也没来得及深究。有知道的朋友,还望留言。
     
    4、再进行xml到java 的转换过程中,XStream对象别名可以定义很多,涵盖的类的范围超过xml所能表达的范围,这个也没有关系,XStream还是会忠实地将xml还原为对象。但是如果xml范围大于XStream所涵盖类的范围,那么转换过程会出错。比如,要将一个Investor节点转换为ManiBody对象,肯定会出错。
  • 相关阅读:
    守护线程
    接口中的方法重写
    jvm内存结构
    浅拷贝,深拷贝
    队列
    12月4号荒度了一天
    同步条件
    条件变量
    信号量Semaphore
    sql练习
  • 原文地址:https://www.cnblogs.com/CoffeeHome/p/3534150.html
Copyright © 2011-2022 走看看