Search code examples
javaxmlxstream

Correct way to construct this xml using Xstream


I'm trying to achieve the following using XStream:

<?xml version="1.0" encoding="UTF-8"?>
<rows>
    <row id="EventID">
        <cell>false</cell>
        <cell>Mainland</cell>
        <cell></cell>
        <cell></cell>

        <row id = "StoreID">
            <cell></cell>
            <cell></cell>
            <cell></cell>
            <cell></cell>
        </row>

    </row>
</rows>

Here we can see that the row with id of "StoreID" is actually a child row of the "EventID" row. I can create both seperately by doing the following:

    String xml = "", eventXML = "", storeXml = "";
    StringBuffer buff = new StringBuffer(1000);
    buff.append("<?xml version='1.0' encoding='iso-8859-1'?>");

    XStream xstream = new XStream(new DomDriver());


    xstream.alias("rows", List.class);
    xstream.alias("row", Event.class);

    xstream.registerConverter(evtConverter);

    for( Event e: events )
    {
        // Get a list of stores
        Store store = e.getStore();
        xstream.registerConverter( storeConverter, XStream.PRIORITY_VERY_HIGH );

        xstream.alias("row", Store.class);
        storeXml = xstream.toXML( store );

        xml = xstream.toXML(e);
    }
    return xml;

So how can I go about combining them? Is there a way to stop the automatic closure of the xml (the Event object) so that I can add in the Store xml?

Thanks


Solution

  • To do this I had to really dilute everything down to basic strings. I created a method that combines the xml strings together:

    private static String combineStrings(String eventXML, String storeXML) {
        String newXML = "";
    
        Pattern pattern = Pattern.compile("</row>");
        Matcher matcher = pattern.matcher(eventXML);
    
        int posForStoreXML = 0;
    
        boolean found = false;
        while (matcher.find()) {
            posForStoreXML = matcher.start() - 1;
            found = true;
        }
        if (!found) {
            System.err.println("No match found");
        }
    
        StringBuilder builder = new StringBuilder(eventXML);
        builder.insert(posForStoreXML, storeXML);
    
        System.out.println(builder.toString());
        newXML = builder.toString();
    
        return newXML;
    }
    

    This had to be called here:

    for (Event_BACKUP e : events) {
            // Get a list of stores
            Store store = e.getStore();
            xstream.registerConverter(storeConverter,
                    XStream.PRIORITY_VERY_HIGH);
            xstream.alias("row", Store.class);
    
            storeXml = xstream.toXML(store);
            xml = xstream.toXML(e);
            **xml = combineStrings(xml, storeXml);**
    
            buffer.append(xml);
        }
        buffer.append( "</rows>" );
        xml = buffer.toString();