XStream, Aliasing and "DuplicateFieldException" - java

I'm trying to write an app so that it is able to read this kind of XML and create an entire object based on it;
<actor id="id273211" PGFVersion="0.19" GSCVersion="0.10.4">
<attributes>
<text id="name">Actor 1b</text>
<point id="position">
<real id="x">0</real>
<real id="y">0</real>
</point>
</attributes>
</actor>
My problem is I'm aliasing members of the class Point as "real" and it gives an exception.
What I have now is;
#XStreamAlias("actor")
public class Actor {
#XStreamAsAttribute
String id = "",PGFVersion = "", GSCVersion = "";
Attributes attributes = new Attributes();
}
public class Attributes {
public Text text = new Text("name", "Actor 1");
public Point point = new Point();
}
#XStreamConverter(value=ToAttributedValueConverter.class, strings={"value"})
#XStreamAlias("text")
public class Text {
#XStreamAsAttribute
String id;
String value;
public Text(String text, String value) {
this.id = text;
this.value = value;
}
public class Point {
#XStreamAlias("real")
public Real x = new Real("x", "11");
#XStreamAlias("real")
public Real y = new Real("y", "21");
#XStreamAsAttribute
public String id = "position";
}
And my Test.java:
public static void main(String[] args) throws Exception {
XStream xstream = new XStream();
Actor actor2 = new Actor();
xstream.processAnnotations(Text.class);
xstream.processAnnotations(Real.class);
xstream.processAnnotations(Point.class);
xstream.processAnnotations(Actor.class);
String xml = xstream.toXML(actor2);
System.out.println(xml);
}
This outputs XML perfectly, as follows:
<actor id="" PGFVersion="" GSCVersion="">
<attributes>
<text id="name">Actor 1</text>
<point id="position">
<real id="x">11</real>
<real id="y">21</real>
</point>
</attributes>
</actor>
But when I try to import it using:
String xml = xstream.toXML(actor2);
Actor actorNew = (Actor)xstream.fromXML(xml);
System.out.println(xml);
It gives an exception:
Exception in thread "main" com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$DuplicateFieldException:
Duplicate field y
---- Debugging information ---- field : y class : projectmerger1.Point required-type : projectmerger1.Point
converter-type :
com.thoughtworks.xstream.converters.reflection.ReflectionConverter
path : /projectmerger1.Actor/attributes/point/real[2]
line number : 6 class[1] :
projectmerger1.Attributes class[2] : projectmerger1.Actor
version : 1.4.6
Is this a wrong setup as a whole or can I continue using it with some tweaks?

I solved it by changing in Point class;
public class Point {
/*
#XStreamAlias("real")
#XStreamAlias("real2")
public Real y = new Real("y", "21");
#XStreamAsAttribute
public String id = "position";
*/
#XStreamImplicit
public List xy = new ArrayList();
public void add(Real entry) {
xy.add(entry);
}
}
and adding this to my Test.java:
actor2.attributes.point.add(new Real("x","0"));
actor2.attributes.point.add(new Real("y","0"));
I'll keep experimenting with this. Thanks for the support.

Related

How to add ObjectNodes with same names?

I am trying to create xml output for web endpoint.
Building xml with ObjectNodes - and i fail to add node with the same name,
So i need
<feature_set>
<feature>
...
</feature>
<feature>
...
</feature>
....
I am trying to do like this, and it won't work:
ObjectNode featureSetNode = ((ObjectNode) sequenceNode).putObject("feature_set");
for (SimpleFeature feature : simpleFeatures ) {
JsonNode featureNode = featureSetNode.putObject("feature");
}
I am getting only one feature node as a result.
How can i add nodes with the same name?
You could let jackson automatically convert the object using annotations like this:
#JacksonXmlRootElement(localName = "feature_set")
public class FeatureRoot {
#JacksonXmlElementWrapper(useWrapping=false) //this removes wrapper tag
#JacksonXmlProperty(localName="feature")
private List<Feature> features;
public FeatureRoot(List<Feature> features) {
this.features = features;
}
public List<Feature> getFeatures() {
return features;
}
}
public class Feature {
private String name;
public Feature(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
The following code
FeatureRoot featureRoot = new FeatureRoot(
List.of(
new Feature("test"),
new Feature("asd")
)
);
XmlMapper mapper = new XmlMapper();
String xml = mapper.writeValueAsString(featureRoot);
will produce
<feature_set>
<feature>
<name>test</name>
</feature>
<feature>
<name>asd</name>
</feature>
</feature_set>
To create same-keys entries from scratch use this:
ObjectNode featureSetNode = sequenceNode.putObject("feature_set");
ArrayNode featureNode = featureSetNode.putArray("feature");
for (SimpleFeature feature : simpleFeatures ) {
ObjectNode featureNodeImpl = featureNode.addObject();
featureNodeImpl.put("start", feature.getSeqRegionStart());
}
XmlMapper mapper = new XmlMapper();
String xml = mapper.writeValueAsString(featureRoot);

Add QName as string to #XmlMixed#XmlAnyElement(lax = true) list

Sorry for the foggy title, I know it does not tell much.
Please consider the following xsd type definition:
<xsd:complexType name="TopicExpressionType" mixed="true">
<xsd:sequence>
<xsd:any processContents="lax" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="Dialect" type="xsd:anyURI" use="required"/>
<xsd:anyAttribute/>
</xsd:complexType>
Complete XSD: http://docs.oasis-open.org/wsn/b-2.xsd
Corresponding JAXB generated Java class:
package org.oasis_open.docs.wsn.b_2;
import org.w3c.dom.Element;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "TopicExpressionType", propOrder = {
"content"
})
public class TopicExpressionType {
#XmlMixed
#XmlAnyElement(lax = true)
protected List<Object> content;
#XmlAttribute(name = "Dialect", required = true)
#XmlSchemaType(name = "anyURI")
protected String dialect;
#XmlAnyAttribute
private Map<QName, String> otherAttributes = new HashMap<QName, String>();
public List<Object> getContent() {
if (content == null) {
content = new ArrayList<Object>();
}
return this.content;
}
public String getDialect() {
return dialect;
}
public void setDialect(String value) {
this.dialect = value;
}
public Map<QName, String> getOtherAttributes() {
return otherAttributes;
}
}
The first goal is to produce an XML like this with JAXB:
<wsnt:TopicExpression Dialect="http://docs.oasis-open.org/wsn/t-1/TopicExpression/Concrete" xmlns:tns="http://my.org/TopicNamespace">
tns:t1/*/t3
</wsnt:TopicExpression>
Please note the followings:
The value of the TopicExpression element is basically a query string that refers to QNames. Example: tns:t1/*/t3
The value of the TopicExpression element contains one or more QName like strings (tns:t1). It must be a string as in the example, it cannot be an Element (e.g.: <my-expresseion>tns:t1/*/t3<my-expresseion/>)
The value of the TopicExpression element is an arbitrary string (at least from the schema's perspective, it follows the rules defined here: https://docs.oasis-open.org/wsn/wsn-ws_topics-1.3-spec-os.pdf page 18)
Even though the value is a string, I need to define the corresponding name space declarations. So if I have an expression like this:
tns:t1 then xmlns:tns has to be declared. If my expresseion is tns:t1/*/tns2:t3 then both xmlns:tns and xmlns:tns2 have to be declared.
The second goal is to get the value of TopicExpression on the other side together with the namespace, using JAXB.
I am completely stuck, I don't know how I could implement this. My only idea is to manually build the value for the TopicExpression and somehow tell the marshaller to include the related namespace declaration despite there is no actual element using it.
Update
Example for a complete SOAP request that includes the before mentioned TopicExpression:
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<env:Header>
<Action xmlns="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeRequest</Action>
<MessageID xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:57182d32-4e07-4f5f-8ab3-24838b3e33ac</MessageID>
</env:Header>
<env:Body>
<ns3:Subscribe xmlns:ns3="http://docs.oasis-open.org/wsn/b-2" xmlns:ns4="http://www.w3.org/2005/08/addressing" >
<ns3:ConsumerReference>
<ns4:Address>http://my-notification-consumer-url</ns4:Address>
</ns3:ConsumerReference>
<ns3:Filter>
<ns3:TopicExpression Dialect="http://docs.oasis-open.org/wsn/t-1/TopicExpression/Simple" xmlns:ns5="http://my.org/TopicNamespace" xmlns:ns6="http://extension.org/TopicNamespace">
ns5:t1/*/ns6:t3
<ns3:TopicExpression/>
</ns3:Filter>
</ns3:Subscribe>
</env:Body>
</env:Envelope>
Not sure, If I have understood your requirement correctly. See if this code sample is helpful for you. If not then maybe try to edit your question a bit and make me understand what exactly you are looking for. I will try to modify and update the code accordingly. Trying with a simple example would be better than providing the complete XSD. Also, look into the following methods: beforeMarshal and afterUnmarshal.
Following is the XML I am trying to marshal and unmarshal
<tns:TopicExpression Dialect="http://docs.oasis-open.org/wsn/t-1/TopicExpression/Concrete" xmlns:tns="http://my.org/TopicNamespace">
tns:t1/*/t3
</tns:TopicExpression>
TopicExpressionType.class:
#Data
#XmlAccessorType(XmlAccessType.FIELD)
public class TestPojo {
#XmlValue
private String TopicExpression;
#XmlAnyAttribute
private Map<String, Object> anyAttributes = new HashMap<>();
}
Main.class:
public class Main {
public static void main(String[] args) throws JAXBException, XMLStreamException {
final InputStream inputStream = Unmarshalling.class.getClassLoader().getResourceAsStream("topic.xml");
final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
final Unmarshaller unmarshaller = JAXBContext.newInstance(TestPojo.class).createUnmarshaller();
final TestPojo topic = unmarshaller.unmarshal(xmlStreamReader, TestPojo.class).getValue();
System.out.println(topic.toString());
StringWriter stringWriter = new StringWriter();
Map<String, String> namespaces = new HashMap<String, String>();
namespaces.put("http://my.org/TopicNamespace", "tns");
Marshaller marshaller = JAXBContext.newInstance(TestPojo.class).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, namespaces);
QName qName = new QName("http://my.org/TopicNamespace","TopicExpression","tns");
JAXBElement<TestPojo> root = new JAXBElement<TestPojo>(qName, TestPojo.class, topic);
marshaller.marshal(root, stringWriter);
String result = stringWriter.toString();
System.out.println(result);
}
}
As you can see as of now I have populated the namespaces map directly. If this is dynamic then you can populate the same in a map and accordingly you can add it while marshaling.
This will provide the following output during the unmarshalling:
TestPojo(TopicExpression=
tns:t1/*/t3
, anyAttributes={Dialect=http://docs.oasis-open.org/wsn/t-1/TopicExpression/Concrete})
During marshaling:
<tns:TopicExpression xmlns:tns="http://my.org/TopicNamespace" Dialect="http://docs.oasis-open.org/wsn/t-1/TopicExpression/Concrete">
tns:t1/*/t3
</tns:TopicExpression>
So the solution I've implemented:
Created a new TopicExpressionType class which has fields not only for the expression but for the namespaces too, used in the expression:
public class TopicExpressionType {
String dialect;
String expression;
List<Namespace> namespaces;
public TopicExpressionType(String dialect, String expression, List<Namespace> namespaces) {
this.dialect = dialect;
this.expression = expression;
this.namespaces = namespaces;
}
public static class Namespace {
String prefix;
String namespace;
public Namespace(String prefix, String namespace) {
this.prefix = prefix;
this.namespace = namespace;
}
public String getPrefix() {
return prefix;
}
public String getNamespace() {
return namespace;
}
}
}
Then implemented an XmlAdapter that is aware of the specifics, knows how to extract namespace prefixes from the expression string and it can read/write namespace declarations on the TopicExpression XML element:
public class TopicExpressionTypeAdapter extends XmlAdapter<Element, TopicExpressionType> {
#Override
public Element marshal(TopicExpressionType topicExpression) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.newDocument();
Element element = document.createElementNS("http://docs.oasis-open.org/wsn/b-2", "mns1:TopicExpression");
element.setAttribute("Dialect", topicExpression.getDialect());
element.setTextContent(topicExpression.getExpression());
for (var ns : topicExpression.namespaces) {
element.setAttribute("xmlns:" + ns.prefix, ns.namespace);
}
return element;
}
#Override
public TopicExpressionType unmarshal(Element arg0) throws Exception {
if (arg0.getFirstChild() instanceof Text text) {
var expression = text.getData();
if (expression == null || expression.isBlank())
throw new TopicExpressionAdapterException("Empty content");
// Extract the prefixes from the expression
var namespacePrefixes = new ArrayList<String>();
getNamespacePrefixes(expression, namespacePrefixes);
//Now get the namespaces for the prefixes
var nsMap = new ArrayList<TopicExpressionType.Namespace>();
for (var prefix : namespacePrefixes) {
var namespace = arg0.getAttribute("xmlns:" + prefix);
if (namespace == null || namespace.isBlank())
throw new TopicExpressionAdapterException("Missing namespace declaration for the following prefix: " + prefix);
nsMap.add(new TopicExpressionType.Namespace(prefix, namespace));
}
var dialect = arg0.getAttribute("Dialect");
if (dialect == null || dialect.isBlank())
throw new TopicExpressionAdapterException("Missing Dialect attribute");
return new TopicExpressionType(dialect, expression, nsMap);
} else {
throw new TopicExpressionAdapterException("Unexpected child element type: " + arg0.getFirstChild().getClass().getName());
}
}
public static class TopicExpressionAdapterException extends Exception {
public TopicExpressionAdapterException(String message) {
super(message);
}
}
}
Note: Implementation of the getNamespacePrefixes() method is left out intentionally from this answer.
The last step is to add the following annotation wherever the TopicExpressionType is used in JAXB generated classes:
#XmlJavaTypeAdapter(TopicExpressionTypeAdapter.class)
TopicExpressionType topicExpression;

JAK generated KML not work with Google My Maps

I write manually a KML file trying to import some polygons in MyMaps. This way works fine:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
<Document>
<Placemark>
<Style>
<PolyStyle>
<color>#a00000ff</color>
<outline>0</outline>
</PolyStyle>
</Style>
<Polygon>
<outerBoundaryIs>
<LinearRing>
<coordinates>9.184254,45.443636 9.183379,45.434288 9.224836,45.431499 9.184254,45.443636</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</Document>
</kml>
I try to write a java program using JAK that generate a most possibile equal file, but it doesn't work with Maps
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns3:kml xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ns3="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:xal="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
<ns3:Document>
<ns3:Placemark>
<ns3:Style>
<ns3:PolyStyle>
<ns3:color>#EABCFF</ns3:color>
<ns3:outline>0</ns3:outline>
</ns3:PolyStyle>
</ns3:Style>
<ns3:Polygon>
<ns3:innerBoundaryIs>
<ns3:LinearRing>
<ns3:coordinates>9.184254,45.443636 9.183379,45.434288 9.224836,45.431499 9.184254,45.443636</ns3:coordinates>
</ns3:LinearRing>
</ns3:innerBoundaryIs>
</ns3:Polygon>
</ns3:Placemark>
</ns3:Document>
</ns3:kml>
That's program:
public static void main(String[] args) throws IOException {
// Style
PolyStyle polystyle = KmlFactory.createPolyStyle();
polystyle.setColor("#EABCFF");
// polystyle.setFill(true);
polystyle.setOutline(false);
//
Kml kml = KmlFactory.createKml();
Document document = kml.createAndSetDocument();
Placemark pm = document.createAndAddPlacemark();
LinearRing linearRing = pm.createAndSetPolygon().createAndAddInnerBoundaryIs().createAndSetLinearRing();
linearRing.addToCoordinates(9.184254, 45.443636, 0);
linearRing.addToCoordinates(9.183379, 45.434288, 0);
linearRing.addToCoordinates(9.224836, 45.431499, 0);
linearRing.addToCoordinates(9.184254, 45.443636, 0);
pm.createAndAddStyle().setPolyStyle(polystyle);
//
kml.marshal(new FileWriter("D:/prova.kml"));
}
I view <ns3: in your kml this make the kml invalid for google maps
Try to correct the file
I had the same problem.
Instead of using kml.marshal(new FileWriter("D:/prova.kml")); I did this...
String name = kml.getClass().getSimpleName();
if ("Kml".equals(name)) {
name = name.toLowerCase();
}
JAXBContext jaxbContext = JAXBContext.newInstance(Kml.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NameSpaceBeautyfier());
JAXBElement<Kml> jaxbKml = new JAXBElement<>(new QName("http://www.opengis.net/kml/2.2", name), (Class<Kml>) kml.getClass(), kml);
jaxbMarshaller.marshal(jaxbKml, file);
With a NameSpaceBeautifier like this ...
private static final class NameSpaceBeautyfier extends NamespacePrefixMapper {
private static final String KML_PREFIX = ""; // DEFAULT NAMESPACE
private static final String KML_URI= "http://www.opengis.net/kml/2.2";
#Override
public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
if(KML_URI.equals(namespaceUri)) {
return KML_PREFIX;
}
return suggestion;
}
#Override
public String[] getPreDeclaredNamespaceUris() {
return new String[] { KML_URI };
}
private NameSpaceBeautyfier() {
}
}
Hope this helps..

XML Value extraction using Java JAXB

I need a help in the following scenario. I have got a XML String response. In that XML response I need to extract three values. I could not achieve it. I have specified the XML response and the value I need. Also I created set of .java file using pojo one line tool.
My XML Response:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<control>
<status>success</status>
<senderid>XXXXX</senderid>
<controlid>ControlIdHere</controlid>
<uniqueid>false</uniqueid>
<dtdversion>3.0</dtdversion>
</control>
<operation>
<authentication>
<status>success</status>
<userid>XXXXX1</userid>
<companyid>XXXXX</companyid>
<sessiontimestamp>2014-08-22T07:12:37-07:00</sessiontimestamp>
</authentication>
<result>
<status>success</status>
<function>readByQuery</function>
<controlid>testControlId</controlid>
<data listtype="customer" count="100" totalcount="5142" numremaining="5042">
<customer>
<name>A</name>
<id>12</id>
</customer>
<customer>
<name>A</name>
<id>12</id>
</customer>
<customer>
<name>A</name>
<id>12</id>
</customer>
</data>
</result>
</operation>
In this XML response I would need the following values
Like count=100, totalcount=5142
My object class is like this
public class Data {
private String totalcount;
private Sodocument[] sodocument;
private String numremaining;
private String count;
private String listtype;
public String getTotalcount ()
{
return totalcount;
}
public void setTotalcount (String totalcount)
{
this.totalcount = totalcount;
}
public Sodocument[] getSodocument ()
{
return sodocument;
}
public void setSodocument (Sodocument[] sodocument)
{
this.sodocument = sodocument;
}
public String getNumremaining ()
{
return numremaining;
}
public void setNumremaining (String numremaining)
{
this.numremaining = numremaining;
}
public String getCount ()
{
return count;
}
}
XMLInputFactory xif = XMLInputFactory.newFactory();
Reader reader = new StringReader(response.toString());
XMLStreamReader xsr = xif.createXMLStreamReader(reader);
JAXBContext jc = JAXBContext.newInstance(Data.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Data jb = unmarshaller.unmarshal(xsr,Data.class).getValue();
System.out.println(jb.getCount());
This is my JAXB class. For the value getCount gives me null response. Can somebody help me on fixing this?
The generated class is too long for me to paste here but here is what you can try:
1) Use freeformatter.com/xsd-generator.html to generate an xsd from your xml. Copy and paste the generated xsd to a file.
2) Use xjc (comes with jdk installation) to generate the java class. It is a command line tool and you just have to run "xjc generated.xsd" and it will generate the annotated version of your class. The generated file will be for the entire xml response - so your class will really be Response.java, not Data.java and you then can drill into the Data element and it's attributes.
Add these annotations:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Data {
#XmlAttribute
private String totalcount;
#XmlElement
private Sodocument[] sodocument;
#XmlAttribute
private String numremaining;
#XmlAttribute
private String count;
#XmlAttribute
private String listtype;
...
But note that Sodocument[] sodocument (which should be a List!) does not match <customer>. Not sure what the model is - could it be another element as well (depending on listtype!)

Xstream isn't attaching an alias for the field

I've defined my xstream like so:
public static final String listToXMLTree(List<?> list,
Class<?> domainClass, Converter evtConverter ) {
String xml = "";
StringBuffer buff = new StringBuffer(1000);
buff.append("<?xml version='1.0' encoding='iso-8859-1'?>");
XStream xstream = new XStream(new DomDriver());
if (list != null && list.size() > 0) {
xstream.registerConverter(evtConverter);
xstream.alias("rows", List.class);
xstream.alias("row", Event.class );
xstream.aliasField("child", Event.class, "hasChildren");
xml = xstream.toXML(list);
} else {
buff.append("<rows/>");
}
xml = buff.append(xml).toString();
System.out.println(xml);
return xml;
}
But the xml that pops out doesn't have any alias for the "hasChildren" variable - why so? The xml looks like this:
<?xml version='1.0' encoding='iso-8859-1'?>
<rows>
<row id="Puerto Rico692014-04-30 00:00:00.02014-07-29 00:00:00.0" xmlkids="1">
<cell></cell>
<cell>Puerto Rico</cell>
<cell>103415</cell>
</row>
</rows>
EDIT
This is the event class that I have - (on a seperate note I tried using the XStream aliases and removed the code above that creates them manually but it didn't work either):
public class Event
{
// Event parameters
private String region;
private boolean hasChildren;
public boolean isHasChildren() {
return hasChildren;
}
public void setHasChildren(boolean hasChildren) {
this.hasChildren = hasChildren;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
}
The evtConverter is a converter that maps the xml that Xstream spits out onto a DHTMLx grid.
Thanks
Credit for this answer goes to Vertex - the converter needed to be added after the aliases in order to work properly - I actually refactored my answer and have the object making use of the Xstream annotations instead of defining them in the method. Here's the code:
/**
* Method to convert list objects to XML using XStream API.
* <p>
*
* #param list
* #param domainClass
* #param columnIds
*/
public static final String listToXML(List<?> list, Class<?> domainClass,
Converter converter) {
String xml = "";
StringBuffer buff = new StringBuffer(1000);
buff.append("<?xml version='1.0' encoding='UTF-8'?>");
XStream xstream = new XStream(new DomDriver());
if (list != null && list.size() > 0) {
xstream.alias("rows", List.class);
xstream.processAnnotations(domainClass);
xstream.registerConverter(converter);
xml = xstream.toXML(list);
} else {
buff.append("<rows/>");
}
xml = buff.append(xml).toString();
return xml;
}

Categories