xStream 问题 - 如何反序列化多个对象

Posted

技术标签:

【中文标题】xStream 问题 - 如何反序列化多个对象【英文标题】:xStream problems - How to deserialize multiple objects 【发布时间】:2011-07-23 22:40:10 【问题描述】:

我正在使用 xStream 来操作 XML。一切都好。放上 XML 存档和其他东西。但是,我有一个问题:

示例:我的 xml 包含一个标签,在这个标签中,我还有一些名为 <comment> 的标签。看一个示例代码:

<comments>
   <comment>
      <id>1</id>
      <desc>A comment</desc>
   </comment>
   <comment>
      <id>2</id>
      <desc>Another comment</desc>
   </comment>
   <comment>
      <id>3</id>
      <desc>Another one comment</desc>
   </comment>
</comments>

并且逐渐地。 我可以在标签内做 500 个标签。这些 cmets 属于注释类型。

如何使用 xStream 进行序列化以将所有这些标签放入类中?我不知道如何在类中让它接收各种对象。

显然,我将使用数组或其他方式来制作它。 但我不知道我该怎么做。

【问题讨论】:

您的 xml 看起来有点不对劲。 &lt;comment&gt; 标签应该以 &lt;/comment&gt; 标签结尾,而不是 &lt;/comments&gt; 标签。另外,这就是你要找的东西吗:***.com/questions/3136234/…? This question 也类似。 【参考方案1】:

对于那个 XML,您可能希望有一个类似的类结构:

public class Comment 
    long id
    String desc


public class Comments 
    List<Comment> comments = new ArrayList<Comment>();

您的解组逻辑将类似于:

XStream xstream = new XStream();
xstream.alias("comments", Comments.class);
xstream.alias("comment", Comment.class);
xstream.addImplicitCollection(Comments.class, "comments");
Comments comments = (Comments)xstream.fromXML(xml);

此外,正如 Nishan 在 cmets 中提到的,您的 XML 格式不完全正确。您需要确保您的&lt;comment&gt;&lt;/comment&gt; 而不是&lt;/comments&gt; 结尾。您需要先解决此问题,然后此答案中的任何代码才能正常工作。

【讨论】:

哦,是的。谢谢你。在我在这里发布的这个 xml 中,我简单地手动制作。 xml 是正确的。所有标签都关闭了正确的标签。感谢您的回答。 @Rob Hruska 我知道有点晚了,但是如何指定 XML 文件位置? @Twhite1195 XML 应该从 FileInputStream 或其他东西中读取。【参考方案2】:

如果您处理多个对象,您可能希望多次调用fromXML(InputStream in) 来获取每个对象。但是,该方法没有按预期处理,并且如果您这样做,则会引发措辞不佳的异常消息。或者,将所有对象包装在一个更大的对象中可能会导致程序使用比预期更多的内存或内存不足。

为了解决这个问题,我创建了一个通用实用程序方法,这样我就可以将每个小对象解析为自己的字符串,这样我就可以使用fromXML(String) 方法并且仍然可以按比例放大。

示例调用:

String element = next(in, "</MyObject>");
MyObject o = (MyObject)xstream.fromXML(element);

public static String next(InputStream in, String occurence) throws IOException 
        StringBuffer sb = new StringBuffer();
        int i;
        int pos = 0;
        while((i = in.read()) != -1) 
            sb.append((char)i);
            if(i == occurence.charAt(pos)) 
                pos ++;
             else 
                pos = 0;

            if(pos == occurence.length())
                return sb.toString();
        
        return null;
    

【讨论】:

【参考方案3】:

虽然是老线程,但这里是注释版:

@XStreamAlias("comment")
public class Comment 
    long id
    String desc


@XStreamAlias("comments")
public class Comments 
    @XStreamImplicit(itemFieldName = "comment")
    List<Comment> comments;

要解组你需要这个:

XStream xStream = new XStream();
xStream.processAnnotations(new Class[]  Comments.class, Comment.class );
Comments comments = (Comments)xStream.fromXML(xml);

【讨论】:

以上是关于xStream 问题 - 如何反序列化多个对象的主要内容,如果未能解决你的问题,请参考以下文章

使用XStream是实现XML与Java对象的转换--持久化

2:如何反序迭代一个序列(字符串,列表,元组)

XSTREAM反序列化漏洞利用之JENKINS(CVE-2016-0792)

利用XStream实现对象XML话

微信公众号xml数据解析之xstream

Java对象表示方式2:XStream实现对对象的XML化