在 Simple 2.5.3 (Java) 中反序列化重复的 XML 元素

发布于 2024-11-12 19:14:02 字数 1074 浏览 2 评论 0原文

假设给出了以下 XML:

<?xml version="1.0" encoding="UTF-8"?>
<ResC>
    <Err text="Error text 1"/>
    <ConRes>
        <Err text="Error text 2"/>
        <ConList>
            <Err text="Error text 3"/>
            <Con>
                <Err text="Error text 4"/>
            </Con>
        </ConList>
    </ConRes>
</ResC>

如您所见, 元素可能出现在 XML 的每个级别上。

使用 Simple 我想反序列化此 XML。因此,我创建了以下类:

@Element(required=false)
public class Err {
    @Attribute
    private String text;

    public void setText(String text) { this.text = text; }

    public String getText() { return text; }
}

但是,我该如何注释 的类;?我真的必须在可能出现的每个类中声明 类型的属性吗?这看起来是很多开销。如果是这样,那么我必须检查每个对象是否包含错误。

有没有更好更简单的方法呢? :-)

谢谢,
罗伯特

Let's say the following XML is given:

<?xml version="1.0" encoding="UTF-8"?>
<ResC>
    <Err text="Error text 1"/>
    <ConRes>
        <Err text="Error text 2"/>
        <ConList>
            <Err text="Error text 3"/>
            <Con>
                <Err text="Error text 4"/>
            </Con>
        </ConList>
    </ConRes>
</ResC>

As you can see the <Err> element may appear on every level of the XML.

Using Simple I would like to deserialize this XML. So, I have created the following class:

@Element(required=false)
public class Err {
    @Attribute
    private String text;

    public void setText(String text) { this.text = text; }

    public String getText() { return text; }
}

However, how do I have to annotate the classes for <ResC>, <ConRes>, <ConList> and <Con>? Do I really have to declare an attribute of type <Err> in every single class in which it may appear? This seems like a lot of overhead. If so, then I would have to check every single object if it contains an error.

Is there any better and easier way? :-)

Thanks,
Robert

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

素食主义者 2024-11-19 19:14:02

需要记住的重要一点是,简单 XML 应该能够遵循您可以使用类逻辑生成的任何结构。因此,您可以创建一个使用错误接口并应用装饰器模式的基类,以便将所有这些传递到具体的错误类,而无需任何实现对象知道它们已被赋予什么。

这可能毫无意义。我只是告诉你怎么样...好吧...我刚刚离开并完全实现了我的想法,这是结果 (完整代码链接):

主文件:

package com.massaiolir.simple.iface;

import java.io.File;

import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;

public class Main {
    public static void main(String[] args) throws Exception {
        Serializer serial = new Persister();
        ResC resc = serial.read(ResC.class, new File("data/testdata.xml"));

        System.out.println(" == Printing out all of the error text. == ");
        System.out.println(resc.getErrorText());
        System.out.println(resc.conRes.getErrorText());
        System.out.println(resc.conRes.conList.getErrorText());
        for (Con con : resc.conRes.conList.cons) {
            System.out.println(con.getErrorText());
        }
        System.out.println(" == Finished printing out all of the error text. == ");
    }
}

它只是简单地运行并显示结果。

BaseObject.java 类:

package com.massaiolir.simple.iface;

import org.simpleframework.xml.Element;

public class BaseObject implements Error {
    @Element(name = "Err", required = false, type = ConcreteError.class)
    private Error err;

    @Override
    public String getErrorText() {
        return err.getErrorText();
    }

    @Override
    public void setErrorText(String errorText) {
        err.setErrorText(errorText);
    }
}

如果所有东西想要“Err”,就应该扩展这个类。

Error 接口:

package com.massaiolir.simple.iface;

public interface Error {
    void setErrorText(String errorText);

    String getErrorText();
}

ConcreteError 类:

package com.massaiolir.simple.iface;

import org.simpleframework.xml.Attribute;

public class ConcreteError implements Error {
    @Attribute
    private String text;

    @Override
    public String getErrorText() {
        return text;
    }

    @Override
    public void setErrorText(String errorText) {
        this.text = errorText;
    }

}

实际的实现类在这一点之后。您会发现它们相当琐碎,因为真正的工作是在上面的类中处理的。

Con 类:

package com.massaiolir.simple.iface;

public class Con extends BaseObject {

}

ConList 类:

package com.massaiolir.simple.iface;

import java.util.ArrayList;

import org.simpleframework.xml.ElementList;

public class ConList extends BaseObject {
    @ElementList(entry = "Con", inline = true)
    public ArrayList<Con> cons;
}

ConRes 类:

package com.massaiolir.simple.iface;

import org.simpleframework.xml.Element;

public class ConRes extends BaseObject {
    @Element(name = "ConList")
    public ConList conList;
}

ResC 类:

package com.massaiolir.simple.iface;

import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;

@Root
public class ResC extends BaseObject {
    @Element(name = "ConRes")
    public ConRes conRes;
}

这就是全部内容是为了它。很简单吧。我能在十分钟内把这一切搞定。实际上,我写这个回复所花费的时间比我编写给您的代码所花费的时间还要长。如果您对我刚刚编写的代码有任何不明白的地方,请告诉我。我希望这可以帮助您了解如何去做这样的事情。

The important thing to remember is that Simple XML should be able to follow any structure that you can logically generate using classes. So you could just create a BaseClass that uses an error interface and applies the Decorator pattern so that it passes all of that through to a concrete error class without any of the implementing objects needing to know what they have been given.

That probably made no sense. How about I just show you...okay...I just went away and implemented exactly what I was thinking and here are the results (full code link):

The Main File:

package com.massaiolir.simple.iface;

import java.io.File;

import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;

public class Main {
    public static void main(String[] args) throws Exception {
        Serializer serial = new Persister();
        ResC resc = serial.read(ResC.class, new File("data/testdata.xml"));

        System.out.println(" == Printing out all of the error text. == ");
        System.out.println(resc.getErrorText());
        System.out.println(resc.conRes.getErrorText());
        System.out.println(resc.conRes.conList.getErrorText());
        for (Con con : resc.conRes.conList.cons) {
            System.out.println(con.getErrorText());
        }
        System.out.println(" == Finished printing out all of the error text. == ");
    }
}

It just runs simple and displays the results.

The BaseObject.java class:

package com.massaiolir.simple.iface;

import org.simpleframework.xml.Element;

public class BaseObject implements Error {
    @Element(name = "Err", required = false, type = ConcreteError.class)
    private Error err;

    @Override
    public String getErrorText() {
        return err.getErrorText();
    }

    @Override
    public void setErrorText(String errorText) {
        err.setErrorText(errorText);
    }
}

This is the class that everything should extend if it wants 'Err'.

The Error interface:

package com.massaiolir.simple.iface;

public interface Error {
    void setErrorText(String errorText);

    String getErrorText();
}

The ConcreteError class:

package com.massaiolir.simple.iface;

import org.simpleframework.xml.Attribute;

public class ConcreteError implements Error {
    @Attribute
    private String text;

    @Override
    public String getErrorText() {
        return text;
    }

    @Override
    public void setErrorText(String errorText) {
        this.text = errorText;
    }

}

The actual implementing classes are after this point. You will see that they are rather trivial because the real work is being handled in the classes above.

The Con class:

package com.massaiolir.simple.iface;

public class Con extends BaseObject {

}

The ConList class:

package com.massaiolir.simple.iface;

import java.util.ArrayList;

import org.simpleframework.xml.ElementList;

public class ConList extends BaseObject {
    @ElementList(entry = "Con", inline = true)
    public ArrayList<Con> cons;
}

The ConRes class:

package com.massaiolir.simple.iface;

import org.simpleframework.xml.Element;

public class ConRes extends BaseObject {
    @Element(name = "ConList")
    public ConList conList;
}

The ResC class:

package com.massaiolir.simple.iface;

import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;

@Root
public class ResC extends BaseObject {
    @Element(name = "ConRes")
    public ConRes conRes;
}

And that is all that there is to it. Pretty simple right. I was able to bang that all out in ten minutes. It actually took me longer to write this response than it took me to write the code that I am giving you. If you do not understand anything about the code that I have just written then please let me know. I hope this helps you to understand how you might go about doing something like this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文