user1658435
user1658435

Reputation: 574

XML to CSV conversion grand child nodes

Sorry if this question is already asked, I had searched different solutions on the website but did not find an appropriate answer for my problem. I have XML like

<Book>
        <Action>NEW</Action>
        <Attributes>
            <Attribute>
                <AttributeName>SwapBook</AttributeName>
                <AttributeValue>A</AttributeValue>
            </Attribute>
            <Attribute>
                <AttributeName>PricerKey</AttributeName>
                <AttributeValue>TRADING</AttributeValue>
            </Attribute>
        </Attributes>
    </Book>

I tried to write the code for converting the XML to a flat CSV file for returning all the header names. But my code is only working for the items at first level.

private List<String> getHeaders(Document document) {
    Element root = document.getDocumentElement();
    NodeList list = root.getChildNodes();
    List<String> headers = new ArrayList<String>();

    for (int i=0; i< list.getLength(); i++) {
        if (list.item(i).getNodeType() == Node.ELEMENT_NODE) {
            Node node = list.item(i);
            NodeList nodeList = node.getChildNodes();
            int children = nodeList.getLength();
            System.out.println("children="+children);
            for (int k = 0; k < children; k++) {
                if (nodeList.item(k).getNodeType() == Node.ELEMENT_NODE) {
                    headers.add(nodeList.item(k).getNodeName());
                }
            }
            break;
    }
}
    return headers;
}

I had seen a post on stack overflow How to get only the top level node's text content with getTextContent() which explains why I'm unable to reach the grand child/child level header names/values. I'm able to print only the Action and Attribute, but the Attribute and AttributeName are not visible.

Any help is sincerely appreciated. Thanks in advance.

Upvotes: 0

Views: 533

Answers (2)

user1658435
user1658435

Reputation: 574

I had come up with the following solution like checking for the child nodes recursively. Please suggest me if I can improve the code in some way.

private void checkChildNodes(Node root){
    if(root.hasChildNodes()){
        NodeList list = root.getChildNodes();
        int length = list.getLength();
        for(int i = 0; i < length; i++){
            if (list.item(i).getNodeType() == Node.ELEMENT_NODE) {
                System.out.println(list.item(i).getNodeName());
                checkChildNodes(list.item(i));
            }
        }
    }
    else{
        System.out.println(root.getNodeName());
    }
}

Thanks.

Upvotes: 0

faljbour
faljbour

Reputation: 1377

try this, it will loop through all the children of all nodes and child nodes,

private List<String> getHeaders(Document document) {
    Element root = document.getDocumentElement();
    NodeList list = root.getChildNodes();
    List<String> headers = new ArrayList<String>();

    for (int i=0; i< list.getLength(); i++) {
        if (list.item(i).getNodeType() == Node.ELEMENT_NODE) {
            Node node = list.item(i);
            addNode(node, headers);
            break;
    }
}
    return headers;
}

private void addNode(Node node, List<String> headers)
{
  NodeList nodeList = node.getChildNodes();
  if(nodeList==null||nodeList.Length==0)return;
  int children = nodeList.getLength();
  for (int k = 0; k < children; k++) {
      if (nodeList.item(k).getNodeType() == Node.ELEMENT_NODE) {
          headers.add(nodeList.item(k).getNodeName());
          addNode(nodeList.item(k), headers);
      }
  }
}

Upvotes: 1

Related Questions