0

I don't have much java/xml experience, so that might be trivial. But given such an xml structure:

<Things>
    <object name="cat" id="0">
        <prop id="1" name="race">ShortHair</prop>
    </object>

    <object name="car" id="1">
        <prop id="1" name="Manufacturer">
            <manufacturer id="1" name="ford">
        </prop>
    </object>

    <object id="2" name="Window">
    </object>
</Things>

is it possible to get specific nodes like for example:

getObject("cat").getRace();

or

getObject("car").getId(1).getManufacturer();

or

getObject(id="2").name;

I know, this is not valid code, but I didn't find examples of xml that appear to do something like this.

thx.

Arpton
  • 7
  • 4
  • you should look for DOM parsing and getting node by attribute. Quite sure this has already been answered here – jhamon Feb 10 '20 at 10:27
  • 1
    look for XPath. – Joop Eggen Feb 10 '20 at 10:31
  • I found some, but they always just iterate through the nodelist and show the attributes, but not trying to access a specific leaf somewhere in the structure. – Arpton Feb 10 '20 at 10:31
  • 1
    It would be possible to write code that acts like this but in essence it would boil down to iterating over the elements at some level and getting one that matches the criteria, e.g. `getObject("car")` could be implemented as iterating over the children of `Things` and returning the first with a `name` attribute that has a value of `"car"` (or return a list in case of multiple cars). – Thomas Feb 10 '20 at 10:32
  • "...they always just iterate through the nodelist and show the attributes" - you could base your code on that: iterate, access the attributes you're interested in and if the values match you use the current node to go deeper. – Thomas Feb 10 '20 at 10:34
  • 1
    https://stackoverflow.com/questions/11863038/how-to-get-the-attribute-value-of-an-xml-node-using-java same question was answered in this link – Mary Fernandes Feb 10 '20 at 10:48

1 Answers1

0

Yes we can fetch elements of XML in Java and there are different ways. Consider this example from tutorials point.

XML:

<class>
   <student rollno = "393">
      <firstname>dinkar</firstname>
      <lastname>kad</lastname>
      <nickname>dinkar</nickname>
      <marks>85</marks>
   </student>

   <student rollno = "493">
      <firstname>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>

   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singh</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
</class>

Java:

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

public class XPathParserDemo {

   public static void main(String[] args) {

      try {
         File inputFile = new File("input.txt");
         DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
         DocumentBuilder dBuilder;

         dBuilder = dbFactory.newDocumentBuilder();

         Document doc = dBuilder.parse(inputFile);
         doc.getDocumentElement().normalize();

         XPath xPath =  XPathFactory.newInstance().newXPath();

         String expression = "/class/student";          
         NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(
            doc, XPathConstants.NODESET);

         for (int i = 0; i < nodeList.getLength(); i++) {
            Node nNode = nodeList.item(i);
            System.out.println("\nCurrent Element :" + nNode.getNodeName());

            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
               Element eElement = (Element) nNode;
               System.out.println("Student roll no :" + eElement.getAttribute("rollno"));
               System.out.println("First Name : " 
                  + eElement
                  .getElementsByTagName("firstname")
                  .item(0)
                  .getTextContent());
               System.out.println("Last Name : " 
                  + eElement
                  .getElementsByTagName("lastname")
                  .item(0)
                  .getTextContent());
               System.out.println("Nick Name : " 
                  + eElement
                  .getElementsByTagName("nickname")
                  .item(0)
                  .getTextContent());
               System.out.println("Marks : " 
                  + eElement
                  .getElementsByTagName("marks")
                  .item(0)
                  .getTextContent());
            }
         }
      } catch (ParserConfigurationException e) {
         e.printStackTrace();
      } catch (SAXException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (XPathExpressionException e) {
         e.printStackTrace();
      }
   }
}

Output:

Current Element :student
Student roll no : 393
First Name : dinkar
Last Name : kad
Nick Name : dinkar
Marks : 85

Current Element :student
Student roll no : 493
First Name : Vaneet
Last Name : Gupta
Nick Name : vinni
Marks : 95

Current Element :student
Student roll no : 593
First Name : jasvir
Last Name : singh
Nick Name : jazz
Marks : 90

As I said there are other ways as well. Check this link for more such examples. XPath is very rich. You can access any element/attribute using XPaths. You can also use XSLT in case you want to transform your XML message into another XML.

CyberMafia
  • 180
  • 8
  • I know that tutorial of course. But I thought there is a more sophisticated way of just looping through until I find the combination I want. Also, if there are more sublevels, it would need more and more for loops, depending on the number of sublevels. – Arpton Feb 10 '20 at 10:39
  • ```xPath.compile(expression)```, you see the expression here. We can give comlpete xpath here and we would not even need to loop through the elements. For example: ```class/student[@rollno="493"]/firstname```. – CyberMafia Feb 10 '20 at 10:43