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
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.
来源:https://stackoverflow.com/questions/6197196/deserialize-repeating-xml-elements-in-simple-2-5-3-java