0

We have a program in Java that needs to convert CSV file to Hierarchy XML:

the output should be like this:

`<?xml version="1.0" encoding="UTF-8"?>
<UteXmlComuniction xmlns="http://www....../data">
    <Client Genaral Data>
        <Client>
            <pfPg></pfPg>  
            <name>Arnold</name>
            <Family>Bordon</family>
        </Client>
        <Contract>
            <ContractDetail>
                <Contract>100020</Contract>
                <ContractYear>2019</ContractYear>
            </ContractDetail>
         </Contract>
    </Client Genaral Data>``

But for CSV file we are flexible, we can define it as we want. I thought maybe in this way it works:

"UteXmlComuniction/ClientGeneralData/Client/pfpg", "UteXmlComuniction/ClientGeneralData/Client/name" , 
"UteXmlComuniction/ClientGeneralData/Client/Family" , ...```

This is our code, but it just gives me the flat XML. Also I can not insert "/" character in CSV file, because program can not accept this character.

public class XMLCreators {
    // Protected Properties

    protected DocumentBuilderFactory domFactory = null;
    protected DocumentBuilder domBuilder = null;

    public XMLCreators() {
        try {
            domFactory = DocumentBuilderFactory.newInstance();
            domBuilder = domFactory.newDocumentBuilder();
        } catch (FactoryConfigurationError exp) {
            System.err.println(exp.toString());
        } catch (ParserConfigurationException exp) {
            System.err.println(exp.toString());
        } catch (Exception exp) {
            System.err.println(exp.toString());
        }

    }

    public int convertFile(String csvFileName, String xmlFileName,
                    String delimiter) {

        int rowsCount = -1;
        try {
            Document newDoc = domBuilder.newDocument();
            // Root element
            Element rootElement = newDoc.createElement("XMLCreators");
            newDoc.appendChild(rootElement);
            // Read csv file
            BufferedReader csvReader;
            csvReader = new BufferedReader(new FileReader(csvFileName));

            int line = 0;
            List<String> headers = new ArrayList<String>(5);

            String text = null;
            while ((text = csvReader.readLine()) != null) {

                StringTokenizer st = new StringTokenizer(text, delimiter, false);
                String[] rowValues = new String[st.countTokens()];
                int index = 0;
                while (st.hasMoreTokens()) {

                    String next = st.nextToken();
                    rowValues[index++] = next;

                }

                if (line == 0) { // Header row

                    for (String col : rowValues) {
                        headers.add(col);
                    }

                } else { // Data row

                    rowsCount++;

                    Element rowElement = newDoc.createElement("row");
                    rootElement.appendChild(rowElement);
                    for (int col = 0; col < headers.size(); col++) {

                        String header = headers.get(col);
                        String value = null;

                        if (col < rowValues.length) {

                            value = rowValues[col];

                        } else {
                            // ?? Default value
                            value = "";
                        }

                        Element curElement = newDoc.createElement(header);
                        curElement.appendChild(newDoc.createTextNode(value));
                        rowElement.appendChild(curElement);

                    }

                }
                line++;

            }

            ByteArrayOutputStream baos = null;
            OutputStreamWriter osw = null;

            try {

                baos = new ByteArrayOutputStream();
                osw = new OutputStreamWriter(baos);

                TransformerFactory tranFactory = TransformerFactory.newInstance();
                Transformer aTransformer = tranFactory.newTransformer();
                aTransformer.setOutputProperty(OutputKeys.INDENT, "yes");
                aTransformer.setOutputProperty(OutputKeys.METHOD, "xml");
                aTransformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

                Source src = new DOMSource(newDoc);
                Result result = new StreamResult(osw);
                aTransformer.transform(src, result);

                osw.flush();
                System.out.println(new String(baos.toByteArray()));

            } catch (Exception exp) {
                exp.printStackTrace();
            } finally {
                try {
                    osw.close();
                } catch (Exception e) {
                }
                try {
                    baos.close();
                } catch (Exception e) {
                }
            }

            // Output to console for testing
            // Resultt result = new StreamResult(System.out);

        } catch (IOException exp) {
            System.err.println(exp.toString());
        } catch (Exception exp) {
            System.err.println(exp.toString());
        }
        return rowsCount;
        // "XLM Document has been created" + rowsCount;
    }
}

Do you have any suggestion that how should I modify the code or how can I change my CSV in order to have a Hierarchy XML?

2
  • If you have the ability to modify the csv, then I suppose you might be having an option to choose the input file format as well. If yes, then I would suggest you to go with json format. CSV isn't apt for this situation, though with efforts it can be done. JSON format would be easy and can be easily converted to XML. Commented Apr 22, 2020 at 16:27
  • Unfortunately the file is CSV format or Excel... We can not go with JSON file... Commented Apr 22, 2020 at 16:44

1 Answer 1

1

csv: pfPg;name;Family;Contract;ContractYear

There are several libs for reading csv in Java. Store the values in a container e.g. hashmap.

Then create java classes representing your xml structure.

class Client {
private String pfPg;
private String name;
private String Family
}

class ClientGenaralData {
private Client client;
private Contract contract;
}

Do the mapping from csv to your Java classes by writing custom code or a mapper like dozer... Then use xml binding with Jackson or JAXB to create xml from Java objects.

Jackson xml Dozer HowTo

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Marc, the issue is that my CSV file is not always the same structure. So I am looking for a Dynamic mode....Don't you have any idea?
I don't think there's a generic way... You could parse csv and store it in a Java container, then serialize it using e.g. jackson to xml. And use xslt to create the final xml structure. You'll need one stylesheet per csv variant, but could reuse some templates.
Thanks, I will go with the solution you mentioned

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.