34

I am trying to parse an XML file from a URL by taking all "<Type>" elements where is parameter type_id="4218"??

XML document:

<BSQCUBS Version="0.04" Date="Fri Dec 9 11:43:29 GMT 2011" MachineDate="Fri, 09 Dec 2011 11:43:29 +0000">
  <Class class_id="385">
    <Title>Football Matches</Title>
    <Type type_id="4264" type_minbet="0.1" type_maxbet="2000.0">
      ...
    </Type>
    <Type type_id="5873" type_minbet="0" type_maxbet="0">
      ...
    </Type>
    <Type type_id="4725" type_minbet="0.1" type_maxbet="2000.0">
      ...
    </Type>
    <Type type_id="4218" type_minbet="0.1" type_maxbet="2000.0">
      ...
    </Type>
    <Type type_id="4221" type_minbet="0.1" type_maxbet="2000.0">
      ...
    </Type>
    <Type type_id="4218" type_minbet="0.1" type_maxbet="2000.0">
      ...
    </Type>
    <Type type_id="4299" type_minbet="0.1" type_maxbet="2000.0">
      ...
    </Type>
  </Class>
</BSQCUBS>

Here is my Java code:

 DocumentBuilder db = dbf.newDocumentBuilder();
 Document doc = db.parse(new URL("http://cubs.bluesq.com/cubs/cubs.php?action=getpage&thepage=385.xml").openStream());

 doc.getDocumentElement().normalize();

 NodeList nodeList = doc.getElementsByTagName("Type");
 System.out.println("ukupno:"+nodeList.getLength());
 if (nodeList != null && nodeList.getLength() > 0) {
   for (int j = 0; j < nodeList.getLength(); j++) {
     Element el = (org.w3c.dom.Element) nodeList.item(j);
     type_id = Integer.parseInt(el.getAttribute("type_id"));
     System.out.println("type id:"+type_id);
   }
 }

This code gives me all elements, I don't want that, I want all elements where the attribute type_id = "4218"!

Andy
  • 8,870
  • 1
  • 31
  • 39
dusmanka
  • 625
  • 1
  • 9
  • 16

5 Answers5

34

XPath is right choice for you:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("<Your xml doc uri>");
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile("//Type[@type_id=\"4218\"]");
NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);

And iterate through nl

korifey
  • 3,379
  • 17
  • 17
8

You're missing a condition inside your loop:

 if(nodeList != null && nodeList.getLength() > 0){
     for (int j = 0; j < nodeList.getLength(); j++) {
         Element el = (org.w3c.dom.Element) nodeList.item(j);
         if (el.hasAttribute("type_id") && el.getAttribute("type_id").equals("4218")) {
              type_id = Integer.parseInt(el.getAttribute("type_id"));

              System.out.println("type id:"+type_id);
         }
     }
}

Also you don't need to test if NodeList returned by getElementsByTagName is null so you can remove the if before the loop.

In general case you might be better off using XPath.

soulcheck
  • 36,297
  • 6
  • 91
  • 90
5

You can use XPath.XPath is used to navigate through elements and attributes in an XML document.There are some good implementations of Xpath in Java.

For you example

XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile("//Type[@type_id=\"4218\"]");
Object exprResult = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodeList = (NodeList) exprResult;
narek.gevorgyan
  • 4,165
  • 5
  • 32
  • 52
3

follow @soulcheck answer below and put a break statement if possible...that could enhance your search.

 if(nodeList != null && nodeList.getLength() > 0){
 for (int j = 0; j < nodeList.getLength(); j++) {
     Element el = (org.w3c.dom.Element) nodeList.item(j);
     if (el.hasAttribute("type_id") && el.getAttribute("type_id").equals("4218")) {
          type_id = Integer.parseInt(el.getAttribute("type_id"));

          System.out.println("type id:"+type_id);
          break;

     }
 }

}

Reddy
  • 65
  • 1
  • 10
2

The following XPath will give you the Type elements you are after:

/BSQCUBS/Class/Type[@type_id=4218]

So you can use the following Java code to get a NodeList that only includes these:

XPathExpression expr = xpath.compile("/BSQCUBS/Class/Type[@type_id=4218]");
NodeList nl = (NodeList)expr.evaluate(doc, XPathConstants.NODESET);
Andy
  • 8,870
  • 1
  • 31
  • 39