我正在尝试反序列化此类XML文档:
<rootelem>
<elementType1 arg1="..." />
<elementType1 arg1="..." />
<elementType1 arg1="..." />
<elementType2 argA="..." argB="..." />
<elementType2 argA="..." argB="..." />
<elementType2 argA="..." argB="..." />
</rootelem>
默认情况下,XStream只能解析这样的形式:
<rootelem>
<list1>
<elementType1 arg1="..." />
<elementType1 arg1="..." />
<elementType1 arg1="..." />
</list1>
<list2>
<elementType2 argA="..." argB="..." />
<elementType2 argA="..." argB="..." />
<elementType2 argA="..." argB="..." />
</list>
</rootelem>
这是因为XStream使用下一个集合格式:
<collection>
<elem .... />
<elem .... />
<elem .... />
</collection>
和框架标签是强制性的。集合只能包含单个类型的节点。那么我该如何解析这样的XML文档呢?现在我已经为此编写了自己的转换器,但我想知道还有其他方法吗?
答案 0 :(得分:1)
我认为Implicit Collections是您的解决方案。
http://x-stream.github.io/alias-tutorial.html#implicit
以下是示例代码:
package com.thoughtworks.xstream;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
Blog teamBlog = new Blog(new Author("Guilherme Silveira"));
teamBlog.add(new Entry("first","My first blog entry."));
teamBlog.add(new Entry("tutorial",
"Today we have developed a nice alias tutorial. Tell your friends! NOW!"));
XStream xstream = new XStream();
xstream.alias("blog", Blog.class);
xstream.alias("entry", Entry.class);
xstream.addImplicitCollection(Blog.class, "entries");
System.out.println(xstream.toXML(teamBlog));
}
}
结果:
<blog>
<author>
<name>Guilherme Silveira</name>
</author>
<entry>
<title>first</title>
<description>My first blog entry.</description>
</entry>
<entry>
<title>tutorial</title>
<description>
Today we have developed a nice alias tutorial. Tell your friends! NOW!
</description>
</entry>
</blog>
答案 1 :(得分:0)
您需要做的第一件事是为所有主要XML标记创建POJO。我假设您提供的示例不是“unmarshall”所需的实际XML(这是用于反序列化的XML术语),但为了给您一个示例来解决这个问题,我将继续使用它; - )。< / p>
public class ElementType1
{
private String arg1;
public ElementType1()
{
setArg1("");
}
public String getArg1()
{
return arg1;
}
public void setArg1(String newArg1)
{
arg1 = newArg1;
}
}
public class ElementType2
{
private String argA;
private String argB;
public ElementType2()
{
setArgA("");
setArgB("");
}
public String getArgA()
{
return argA;
}
public void setArgA(String newArgA)
{
argA = newArgA;
}
public String getArgB()
{
return argB;
}
public void setArgB(String newArgB)
{
argB = newArgB;
}
}
public class RootElement
{
private List<ElementType1> element1s;
private List<ElementType2> element2s;
public RootElement()
{
setElement1s(new ArrayList<ElementType1>());
setElement2s(new ArrayList<ElementType2>());
}
public List<ElementType1> getElement1s()
{
return element1s;
}
public void setElement1s(List<ElementType1> newElement1s)
{
element1s = newElement1s;
}
public List<ElementType2> getElement2s()
{
return element2s;
}
public void setElement2s(List<ElementType2> newElement2s)
{
element2s = newElement2s;
}
}
现在您已经拥有了POJO,使用XStream进行编组(序列化)和解组(反序列化)它们非常容易。
List<ElementType1> e1 = new ArrayList<ElementType1>();
List<ElementType2> e2 = new ArrayList<ElementType2>();
ElementType1 a, b, c;
a = new ElementType1();
b = new ElementType1();
c = new ElementType1();
a.setArg1("fizz");
b.setArg1("buzz");
c.setArg1("foo");
e1.add(a);
e1.add(b);
e1.add(c);
ElementType2 d, e;
d = new ElementType2();
e = new ElementType2();
d.setArgA("flim");
d.setArgB("flam");
e.setArgA("something");
e.setArgB("blah");
e2.add(d);
e2.add(e);
RootElement rootElem = new RootElement();
rootElem.setElement1s(e1);
rootElem.setElement2s(e2);
XStream xstream = new XStream();
RootElement rootElem = getYourRootElementSomehow();
String rootElementAsXml = xstream.toXML(rootElem);
System.out.println(rootElementAsXml);
此代码现在将以下内容打印到控制台:
<fully.qualified.pkg.name.RootElement>
<element1s>
<fully.qualified.pkg.name.ElementType1>
<arg1>fizz</arg1>
</fully.qualified.pkg.name.ElementType1>
<fully.qualified.pkg.name.ElementType1>
<arg1>buzz</arg1>
</fully.qualified.pkg.name.ElementType1>
<fully.qualified.pkg.name.ElementType1>
<arg1>foo</arg1>
</fully.qualified.pkg.name.ElementType1>
</element1s>
<element2s>
<fully.qualified.pkg.name.ElementType2>
<argA>flim</argA>
<argB>flam</argB>
</fully.qualified.pkg.name.ElementType2>
<fully.qualified.pkg.name.ElementType2>
<argA>something</argA>
<argB>blah</argB>
</fully.qualified.pkg.name.ElementType2>
</element2s>
</fully.qualified.pkg.name.RootElement>
然后,您可以使用XStreams多功能“别名”方法清理名为XML元素的令人讨厌的,完全限定的包,如下所示:
xstream.alias("elementType1", ElementType1.class);
xstream.alias("elementType2", ElementType2.class);
xstream.alias("rootElement", RootElement.class);
String rootElementAsXml = xstream.toXML(rootElem);
System.out.println(rootElementAsXml);
现在将打印出来:
<rootElement>
<element1s>
<elementType1>
<arg1>fizz</arg1>
</elementType1>
<elementType1>
<arg1>buzz</arg1>
</elementType1>
<elementType1>
<arg1>foo</arg1>
</elementType1>
</element1s>
<element2s>
<elementType2>
<argA>flim</argA>
<argB>flam</argB>
</elementType2>
<elementType2>
<argA>something</argA>
<argB>blah</argB>
</elementType2>
</element2s>
</rootElement>
现在我知道在您的示例中,您希望所有<arg>
实际上都是<elementType>
代码的属性,而不是子代标记自己。您可以使用XStream强大的API为您执行此操作,无论您喜欢什么。但希望这足以让你开始。
顺便说一句,将XML转换回POJO同样简单:
RootElement root = (RootElement)xstream.fromXML(rootElementAsXml);
根据经验,XStream是一个“oxmapper”(Object-XML Mapper),它预先构建为知道如何将POJO转换为有意义的XML,反之亦然。你总是可以覆盖它的默认值,但更常见的是,我总是发现自己对它的默认值有多聪明感到惊讶。祝你好运。