Dhinakar
Dhinakar

Reputation: 4151

Group values based on xml tags

I have a xml file which have tags like.

<ENVELOPE>
    <A>Hi
    </A>

    <A1>
        <A12>groupA</A12>
        <A13></A13>
    </A1>
    <B>
        <A>xxx</A>
    </B>
    <C>
        <A11>100</A11>
        <A13></A13>
    </C>
    <B>
        <A>yyy</A>
    </B>
    <C>
        <A11>1000</A11>
        <A13></A13>
    </C>
    <B>
        <A>zzz</A>
    </B>
    <C>
        <A11>100</A11>
        <A13></A13>
    </C>
    <A>Hello</A>
    <A1>
        <A12>groupC</A12>
        <A13></A13>
    </A1>
    <B>
        <A>rrr</A>
    </B>
    <C>
        <A11>10000</A11>
        <A13></A13>
    </C>
</ENVELOPE>

I want to store these data in below format

Col Header A    A1         B   C-A11
           Hi   groupA    xxx   100   
           Hi   groupA    yyy   1000    
           Hi   groupA    zzz   100     
          Hello groupB    rrr   10000   

Tried source code:

   DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
  domFactory.setNamespaceAware(true); 
  DocumentBuilder builder = domFactory.newDocumentBuilder();
  Document doc = builder.parse("Response.xml");
  XPath xpath = XPathFactory.newInstance().newXPath();
  // XPath Query for showing all nodes value

  ArrayList names = new ArrayList();

  XPathExpression expr1 = xpath.compile("//A/text()");

  Object res = expr1.evaluate(doc, XPathConstants.NODESET);
  NodeList nod = (NodeList) res;

  for (int i = 0; i < nod.getLength(); i++) {
      System.out.print(i+":");
        System.out.println(nod.item(i).getNodeValue()); 
        if(!names.contains(nod.item(i).getTextContent().trim()))
            names.add(nod.item(i).getTextContent().trim());
 }

  NodeList nodeLst = doc.getElementsByTagName("C");

   int coun = nodeLst.getLength();
   String val[][] = new String[coun][2];
  for (int s = 0; s < nodeLst.getLength(); s++) {
     Node secNode = nodeLst.item(s);

     if (secNode.getNodeType() == Node.ELEMENT_NODE) {
       try
              {
                Element amtval = (Element) secNode;
                NodeList secval = amtval.getElementsByTagName("A11");
                val[s][0] = secval.item(0).getTextContent();
                    System.out.println("A11 :" + val[s][0]);

                NodeList lstNmElmntLst = amtval.getElementsByTagName("A13");
                val[s][1] = lstNmElmntLst.item(0).getTextContent();
                    System.out.println("A13 : " +val[s][1]);
              }
              catch(Exception ex){
                  ex.printStackTrace();
             }
     }
  }

   NodeList plamt = doc.getElementsByTagName("A1");

   int count = plamt.getLength();
   String val1[][] = new String[count][2];
  for (int s = 0; s < plamt.getLength(); s++) {
      Node secNode = plamt.item(s);

     //if (secNode.getNodeType() == Node.ELEMENT_NODE)
     {
       try
              {
                Element amtval = (Element) secNode;
                NodeList secval = amtval.getElementsByTagName("A12");
                val1[s][0] = secval.item(0).getTextContent();
                    System.out.println("A12 :" + val1[s][0]);

                NodeList lstNmElmntLst = amtval.getElementsByTagName("A13");
                val1[s][1] = lstNmElmntLst.item(0).getTextContent();
                    System.out.println("A13: " +val1[s][1]);
              }
              catch(Exception ex){
                  ex.getMessage();
             }
     }

I got below output

Hi      100     100
xxx     100         100
yyy     100         100
zzz     100         100
Hello   groupA  groupB
rrr     groupC  groupD
  1. How can get as mentioned format.
  2. Is there any references available for grouping?
  3. Please provide any logic to do this Help me. Thanks in advance, Dhina P.

Upvotes: 0

Views: 687

Answers (1)

Michael Kay
Michael Kay

Reputation: 163458

I certainly wouldn't attempt this in navigational Java code - the XSLT solution will be much easier. I think it's this:

<xsl:for-each select="B">
  <tr>
    <td><xsl:value-of select="preceding-sibling::A[1]"/></td>
    <td><xsl:value-of select="preceding-sibling::A1[1]"/></td>
    <td><xsl:value-of select="child::A"/></td>
    <td><xsl:value-of select="following-sibling::C[1]/A11"></td>
  </tr>
</xsl:for-each>

Upvotes: 2

Related Questions