Rory's Blog
Happy study,Happy work,Happy life
posts - 22,  comments - 46,  trackbacks - 0
xstream是个好东西。对于配置文件的读取很方便。在mybog中我就用到了。不过今天打算用yupoo的api来做相册。发现xstream对于xmlnode的attribute解析支持不是那么的好。
对于这种节点格式的非常的简单
<result>
    
<page>1</page>
    
<pages>1</pages>
    
<perpage>100</perpage>
    
<total>19</total>
    
<photos>
        
<photo>
            
<id>ff8080810fc8ac78010fd3f158d40a52</id>
            
<owner>ff8080810f1a387b010f1a83d6530dfc</owner>
            
<title>Gmail-2</title>
            
<host>4</host>
            
<dir>20061230</dir>
            
<filename>231905_1463411198</filename>
        
</photo>
    
</photos>
</result>

简单的alias一下就可以读到值了
File file = new File("src/test/java/com/jdkcn/test/result.xml");
BufferedReader reader 
= new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
XStream stream 
= new XStream();
stream.alias(
"result", YupooResult.class);
stream.alias(
"photo",YupooPhoto.class);
YupooResult result 
= (YupooResult)stream.fromXML(reader);
可是Yupoo的api返回的xmlrpc的结果是这样的
<result page="1" pages="1" perpage="100" total="19">
    
<photos>
        
<photo id="ff8080810fc8ac78010fd3f158d40a52"
            owner
="ff8080810f1a387b010f1a83d6530dfc" title="Gmail-2" host="4"
            dir
="20061230" filename="231905_1463411198" />
    
</photos>
</result>
这样就load不到值了。没法去mailist里面找答案,果然有人问。
Hello,

I am not sure about the subject but here is what I needed help for:

XML:

<field name="value">I am a Field.</field>

I have already tried several structures and nothing seem to work.

Is this possible for XStream? :)

How is the Java class form to support this?

Thanks!




有人回答是看Converter的文档。果然找到答案了。
自己写一个converter就可以了。
下面是我的converter
package com.jdkcn.xstream;

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

import com.jdkcn.yupoo.YupooPhoto;
import com.jdkcn.yupoo.YupooResult;
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 <a href="mailto:rory.cn@gmail.com">somebody</a>
 * 
@since Jan 16, 2007 6:12:35 PM
 * 
@version $Id YupooResultConverter.java$
 
*/
public class YupooResultConverter implements Converter {
    
/* (non-Javadoc)
     * @see com.thoughtworks.xstream.converters.Converter#marshal(java.lang.Object, com.thoughtworks.xstream.io.HierarchicalStreamWriter, com.thoughtworks.xstream.converters.MarshallingContext)
     
*/
    
public void marshal(Object obj, HierarchicalStreamWriter writer, MarshallingContext context) {
        
// FIXME unfinish.
    }

    
/* (non-Javadoc)
     * @see com.thoughtworks.xstream.converters.Converter#unmarshal(com.thoughtworks.xstream.io.HierarchicalStreamReader, com.thoughtworks.xstream.converters.UnmarshallingContext)
     
*/
    
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
        YupooResult result 
= new YupooResult();
        result.setPage(
new Integer(reader.getAttribute("page")));
        result.setPages(
new Integer(reader.getAttribute("pages")));
        result.setPerpage(
new Integer(reader.getAttribute("perpage")));
        result.setTotal(
new Integer(reader.getAttribute("total")));
        reader.moveDown();
        List
<YupooPhoto> photos = new ArrayList<YupooPhoto>();
        
while(reader.hasMoreChildren()) {
            reader.moveDown();
            YupooPhoto photo 
= new YupooPhoto();
            photo.setDir(reader.getAttribute(
"dir"));
            photo.setFilename(reader.getAttribute(
"filename"));
            photo.setHost(reader.getAttribute(
"host"));
            photo.setId(reader.getAttribute(
"id"));
            photo.setOwner(reader.getAttribute(
"owner"));
            photo.setTitle(reader.getAttribute(
"title"));
            photos.add(photo);
            reader.moveUp();
        }
        result.setPhotos(photos);
        
return result;
    }
    
/* (non-Javadoc)
     * @see com.thoughtworks.xstream.converters.ConverterMatcher#canConvert(java.lang.Class)
     
*/
    
public boolean canConvert(Class clazz) {
        
return clazz.equals(YupooResult.class);
    }
}

然后调用的地方修改一下就ok了。
XStream stream = new XStream();
stream.registerConverter(
new YupooResultConverter());
stream.alias(
"result", YupooResult.class);



参考:
http://xstream.codehaus.org/converter-tutorial.html

2007年1月18日更新。
这里感谢网友 Ivan Chen(西滨) 的提示。原来新版的xstream可以简单的解决了。在1.2.1的doc里面找到了这个两个方法。

useAttributeFor

public void useAttributeFor(java.lang.String fieldName,
                            java.lang.Class type)
Use an XML attribute for a field or a specific type.

Parameters:
fieldName - the name of the field
type - the Class of the type to be rendered as XML attribute
Throws:
XStream.InitializationException - if no AttributeMapper is available
Since:
1.2

useAttributeFor

public void useAttributeFor(java.lang.Class type)
Use an XML attribute for an arbotrary type.

Parameters:
type - the Class of the type to be rendered as XML attribute
Throws:
XStream.InitializationException - if no AttributeMapper is available
Since:
1.2

这两个方法都是从1.2开始支持的。
也不用自己写converter了。这样就可以了
        stream.alias("result", YupooResult.class);
        stream.useAttributeFor(
"page", Integer.class);
        stream.useAttributeFor(
"pages", Integer.class);
        stream.useAttributeFor(
"perpage", Integer.class);
        stream.useAttributeFor(
"total", Integer.class);
        stream.alias(
"photo", YupooPhoto.class);
        stream.useAttributeFor(
"id", String.class);
        stream.useAttributeFor(
"owner", String.class);
        stream.useAttributeFor(
"title", String.class);
        stream.useAttributeFor(
"host", String.class);
        stream.useAttributeFor(
"dir", String.class);
        stream.useAttributeFor(
"filename", String.class);

创造共用协议:署名,非商业,保持一致
   除经特别注明外,本文章版权归莫多泡泡所有.
署名,非商业用途,保持一致.   somebody(莫多)
posted on 2007-01-17 18:24 莫多 阅读(7983) 评论(2)  编辑  收藏 所属分类: Other

FeedBack:
# re: xstream对xmlnode的属性(attribute)解析的问题。
2007-01-18 09:19 | Ivan Chen(西滨)
新版的xstream不用那么麻烦了(说实话,要自己写一个converter倒不如直接用jdom好了)
对于attribute,这样写
stream.useAttributeFor("id",String.class);
就可以。好像也没有顺序问题?  回复  更多评论
  
# re: xstream对xmlnode的属性(attribute)解析的问题。[未登录]
2007-01-18 10:05 | 莫多
哦。是么?赶紧下载一个新版试试。  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 

<2007年1月>
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910

常用链接

留言簿(1)

随笔分类(27)

随笔档案(22)

Friends

搜索

  •  

积分与排名

  • 积分 - 61891
  • 排名 - 845

最新评论

阅读排行榜

评论排行榜