Десериализовать повторяющиеся элементы XML в Simple 2.5.3 (Java) - PullRequest
1 голос
/ 01 июня 2011

Допустим, задан следующий 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>

Как видите, элемент <Err> может появляться на каждом уровне XML.

Использование Простой Я бы хотел десериализовать этот XML. Итак, я создал следующий класс:

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

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

    public String getText() { return text; }
}

Однако как мне аннотировать классы для <ResC>, <ConRes>, <ConList> и <Con>? Действительно ли мне нужно объявлять атрибут типа <Err> в каждом отдельном классе, в котором он может появляться? Это похоже на много накладных расходов. Если так, то я должен был бы проверить каждый объект, если он содержит ошибку.

Есть ли способ лучше и проще? : -)

Спасибо
Роберт

1 Ответ

0 голосов
/ 12 июня 2011

Важно помнить, что Simple XML должен следовать любой структуре, которую вы можете логически генерировать с помощью классов. Таким образом, вы можете просто создать BaseClass, который использует интерфейс ошибок и применяет шаблон Decorator, чтобы он передавал все это в конкретный класс ошибок, при этом ни одному из реализующих объектов не нужно знать, что им было дано.

Это, вероятно, не имело смысла. Как насчет того, чтобы я просто показал вам ... хорошо ... Я просто ушел и реализовал именно то, о чем думал, и вот результаты ( полный код ссылки ):

Основной файл:

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».

Интерфейс ошибки:

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;
}

И это все, что есть. Довольно просто верно. Я смог ударить все это за десять минут. На самом деле мне потребовалось больше времени для написания этого ответа, чем для написания кода, который я вам даю. Если вы ничего не понимаете в коде, который я только что написал, пожалуйста, дайте мне знать. Надеюсь, это поможет вам понять, как вы можете поступить так, как это.

...