XStream несколько типов узлов в коллекции - PullRequest
0 голосов
/ 11 ноября 2011

Я пытаюсь десериализовать такой 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-документ? Теперь я написал свой собственный конвертер для этого, но мне интересно, есть ли другие способы?

Ответы [ 2 ]

1 голос
/ 16 ноября 2013

Я думаю, что Implicit Collections - это решение для вас.

http://x -stream.github.io / псевдоним tutorial.html # неявное

Вот пример кода:

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>
0 голосов
/ 12 ноября 2011

Первое, что вам нужно сделать, это создать POJO s для всех ваших основных тегов XML.Я предполагаю, что приведенный вами пример - это не фактический XML, который вам нужен для «unmarshall» (это язык XML для десериализации), но я приведу его для того, чтобы дать вам пример для работы; -).

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 для маршалинга (сериализации) и демаршаллизации (десериализации) их в и из XML довольно просто.

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>

Затем вы можете очистить вредоносный, полностью определенный пакет с именем XML-элементов, используя универсальные методы «псевдонимов» XStreams, например:

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> s фактически были атрибутами из<elementType> теги, а не дочерние теги.Вы можете использовать мощный API XStream, чтобы сделать это для вас, как вам угодно.Но, надеюсь, этого достаточно, чтобы вы начали.

И, кстати, превратить ваш XML обратно в POJO так же просто:

RootElement root = (RootElement)xstream.fromXML(rootElementAsXml);

Как правило, XStream"oxmapper" (Object-XML Mapper), и он поставляется предварительно собранным, чтобы знать, как превратить ваш POJO в значимый XML и наоборот.Вы всегда можете переопределить его значения по умолчанию, но чаще всего я всегда удивляюсь, насколько умными являются его значения по умолчанию.Желаем удачи.

...