0

i am working on converting CSV to XML, though i have many ways to do this but my requirement is to do it in such a way that in future the mapping can be changed without any code change. so we are using the following approach. we are using Apache camel for the integration so CSV is being converted out of the box by camel and is being provided as a List<List<String>> with data something like

{[header1,header2,header3],[1,2,3],[2,4,5]}

i need to convert this list data to XML is the defined form but since i can't use the java mapping so was planning to do something like to convert this List in to a flat XML file using XStream and than use xslt to map the raw XML file to xslt, but when i am XStream to convert List to XML it giving following output

<list>
  <java.util.Arrays_-ArrayList>
    <a class="string-array">
      <string>Quantity</string>
      <string>Price</string>
      <string>Total</string>
      <string>Date</string>
      <string>ID</string>
      <string>Name</string>
      <string>Ref#</string>
    </a>
  </java.util.Arrays_-ArrayList>
  <java.util.Arrays_-ArrayList>
    <a class="string-array">
      <string>4</string>
      <string>1.13</string>
      <string>4.52</string>
      <string>9/4/2008</string>
      <string>275</string>
      <string>Blue Ink</string>
      <string>49385730</string>
    </a>
  </java.util.Arrays_-ArrayList>
  <java.util.Arrays_-ArrayList>
    <a class="string-array">
      <string>5</string>
      <string>2.16</string>
      <string>2.16</string>
      <string>8/3/2008</string>
      <string>229</string>
      <string>Red Ink</string>
      <string>20549348</string>
    </a>

my sample CSV is

Quantity,Price,Total,Date,ID,Name,Ref#
4,1.13,4.52,9/4/2008,275,Blue Ink,49385730
5,2.16,2.16,8/3/2008,229,Red Ink,20549348

so it seems not possible to map this raw XML to the required XML using XSLT. Is there any way to convert this List data in to some more presentable XML format so that we can map that XML with XSLT to avoid any code change. Or is there any other more efficient way to convert this list in to XML structure

Thanks in advance

Umesh Awasthi
  • 23,407
  • 37
  • 132
  • 204
  • What is the required XML and what problems do you encounter when transforming the XStream output to that required XML format? – Olaf Jul 22 '11 at 14:49
  • @ Olaf: final XML can be any format as decided by the team but my main concern is what XStream is giving as output, since the one output i have placed in the post seems not able to fullfill my goal since i will not able to use XSLT in that,all i want is that the output from XStream should be like the header value should work as tags and there values should be inside the tags so that i can use XSLT for converting it to required format – Umesh Awasthi Jul 22 '11 at 16:07

3 Answers3

1

This was more complex than I thought, mostly due to the List input:

    final List<String> headers = Arrays.asList("Quantity", "Price");
    final List<String> row1 = Arrays.asList("1", "2");
    final List<String> row2 = Arrays.asList("3", "4");
    final XStream xStream = new XStream();
    xStream.autodetectAnnotations(true);
    final String xml = xStream.toXML(new Container(new Headers(headers), Arrays.asList( row1, row2)));

This will give you:

<Container>
  <Headers>
    <header>Quantity</header>
    <header>Price</header>
  </Headers>
  <Part>
    <Item>1</Item>
    <Item>2</Item>
  </Part>
  <Part>
    <Item>3</Item>
    <Item>4</Item>
  </Part>
</Container>

Container:

@XStreamAlias("Container")
class Container {
    @XStreamAlias("Headers")
    private final Headers headers;

    @XStreamImplicit(itemFieldName = "Part")
    private final List<LineItem> items = new ArrayList<LineItem>();

    Container(final Headers headers, final List<List<String>> stringItems) {
        this.headers = headers;
        for (List<String> item : stringItems) {
            items.add(new LineItem(item));
        }
    }
}

Headers:

@XStreamAlias("Headers")
public class Headers {
    @XStreamImplicit(itemFieldName = "header")
    private final List<String> headers;

    public Headers(final List<String> headers) {
        this.headers = headers;
    }
}

and LineItems:

@XStreamAlias("Items")
public class LineItem {
    @XStreamImplicit(itemFieldName = "Item" )
    private final List<String> items;

    public LineItem(final List<String> items) {
        this.items = items;
    }
}
Paul McKenzie
  • 19,646
  • 25
  • 76
  • 120
  • The actual problem was described in the comments rather than the question itself. OP wants to generate XML with element tags defined by the header line. I don't believe you can do it with XStream. I propose to use DOM4J. – Olaf Jul 22 '11 at 17:17
1

The way how the generated XML is described (headers become the element tags), it is really hard to generate without custom programming. The best bet would be to write some code yourself using DOM4J.

Olaf
  • 6,249
  • 1
  • 19
  • 37
0

I think XSLT can do the job:

You can use the position() function of xslt to navigate to the right column identifier within the first list entry when you iterate over all the list entries.

Omnaest
  • 3,096
  • 1
  • 19
  • 18