2

I'm new in Java. Want some advice. So, I'm parsing data from Xml file, and adding it to hashMap. Please take a look at a piece of code:

final HashMap<String,String> urls = new HashMap<String,String>();

        File products = new File("D:/eclipse/workspace/test/src/main/resources/Products.xml");
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder;

        dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(products);
        doc.getDocumentElement().normalize();

        NodeList nList = doc.getElementsByTagName("Row");                       
        for (int z=0; z<nList.getLength(); z++) {
        Node nNode = nList.item(z);
        Element eElement = (Element) nNode; 

        NodeList a = eElement.getElementsByTagName("item");
        for (int i=0; i<a.getLength(); i++) {                               
            String b = eElement.getElementsByTagName("item").item(i).getTextContent();
            String c = eElement.getElementsByTagName("url").item(i).getTextContent();           
            urls.put(b, c);
            System.out.println(urls);                               
                }
            }

This is my output of hashMap after println in Console:

{Select product=bla-bla-bla}
{Single Landmine Shirt=http://www.sample.com/landmine-single-shirt, Select product=bla-bla-bla}
{Women's Silver & Black Bar=http://www.sample.com/womens-silver-and-black-bar, Single Landmine Shirt=http://www.sample.com/landmine-single-shirt, Select product=bla-bla-bla}

As you see, I have progressive set of items with every next iteration of for-cycle :(. But what I really need - is just key(item tag)=value(url tag) pairs in each line. "item" and "url" - are tags from my XML (please see Attached).

I 'd like to have output like this (just one key and one corresponding value):

{Select product=bla-bla-bla}
{Single Landmine Shirt=http://www.sample.com/landmine-single-shirt}
{Women's Silver & Black Bar=http://www.sample.com/womens-silver-and-black-bar}
{High Density Foam Rollers=http://www.sample.com/high-density-foam-rollers}

How can I update code for getting correct key-value pairs? Will be glad for any answers. Thank you very much! Products.xml

Evg Evg
  • 199
  • 9
  • 1
    1) `System.out.println("{" + b + "=" + c + "}");` --- Or 2) Move `println()` method outside loop. – Andreas Dec 12 '15 at 01:06
  • Calling `normalize()` will not affect result, so it's a waste of CPU cycles. `getTextContent()` will merge text content, if needed. – Andreas Dec 12 '15 at 01:08
  • 1
    @Andreas, thanks. Since I need store values in hashMap and use it further, seems your suggestion number 2) is fit here. I'm appreciate your answer man. – Evg Evg Dec 12 '15 at 22:20

2 Answers2

2

Try this:

final HashMap<String, String> urls = new HashMap<String, String>();

File products = new File("D:/eclipse/workspace/test/src/main/resources/Products.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder;

dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(products);
doc.getDocumentElement().normalize();

NodeList rowsList = doc.getElementsByTagName("Row");
for(int z = 0; z < rowsList.getLength(); z++)
{
    Node rowNode = rowsList.item(z);
    NodeList rowNodeChildren = rowNode.getChildNodes();
    String item = null;
    String url = null;
    for(int i = 0; i < rowNodeChildren.getLength(); i++)
    {
        Node rowNodeChild = rowNodeChildren.item(i);
        if("item".equals(rowNodeChild.getNodeName()))
        {
            item = rowNodeChild.getTextContent();
        }
        else if("url".equals(rowNodeChild.getNodeName()))
        {
            url = rowNodeChild.getTextContent();
        }
    }
    urls.put(item, url);
}
Josh Chappelle
  • 1,449
  • 1
  • 12
  • 28
  • This is good update for my code, Josh. Thank you! And as I see it from functional side - the result of your code is same as mine. Anyway, what I've got from other answers: the solution - is just moving **println** outside the loop. Thank you very much again for suggestion. – Evg Evg Dec 12 '15 at 22:38
2

What you get is normal. I explain it:

  • you populate your Map, by iterating over items
  • and you println this Map, at each step.

Then, as you want just item=url once, I suggest:

Solution 1: dont use your Map for this (keep it if you want to use it after), and just replace

urls.put(b, c);
System.out.println(urls);  

by

 System.out.println("{"+b+"="+c+"}");

Solution 2: keep you Map, but just move your println outside your loop

You will have this once

{Women's Silver & Black Bar=http://www.sample.com/womens-silver-and-black-bar, Single Landmine Shirt=http://www.sample.com/landmine-single-shirt, Select product=bla-bla-bla}

It depends on your choice of formatting

  • 1
    so yeah I need to keep Map for sure. And solution number 2 works for me. Big thank! :) I have one lil question here: now it stores in line(String) view as You described in answer, I mean {item=url, item2=url2, etc.} My question: is it possible to store values by pairs in column view? - like this: {item=utl} \n {item2=utl2} \n {item3=utl3} \n etc. ...Thanks! – Evg Evg Dec 12 '15 at 22:27
  • 1
    @EvgEvg, in fact, it is not keep in line, or column, there is an internal structure. If you want to print line, by line, just read how to iterate a Map: http://stackoverflow.com/questions/46898/iterate-over-each-entry-in-a-map – guillaume girod-vitouchkina Dec 14 '15 at 17:35