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日更新。
这里感谢网友  的提示。原来新版的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 
莫多 阅读(8031) 
评论(2)  编辑  收藏  所属分类: 
Other