helpdesk
helpdesk

Reputation: 2074

Retrieving attributes and values of child Nodes of an XML Element in Java

Please, how can I get the attribute value of the second in the XML course tag name with attribute "AdvancedAlgorithm" in the XML structure below:

<course name="AdvancedAlgorithm">
    <Teacher name="Francis" class="A" />
    <Teacher name="John" class="B" />
    <Teacher name="Philips" class="C" />
    <course name="AlgorithmForBeginners">
        <Teacher name="Simon" class="E" />
        <Teacher name="Joan" class="F" />
    </course>
    <Teacher name="Edward" class="M" />
</course>

I have tried various means to get it but somehow it gives me first a wrong length and a wrong value.. what am I doing wrong in the code below?

 public void getStructure(NodeList list){

    for(int i= 0;i<list.getLength();i++){
        Element element = (Element)list.item(i);
           if(element.getNodeType()==Node.ELEMENT_NODE && element.getAttribute("name").equals("AdvancedAlgorithm"))
         {
                NodeList node = element.getChildNodes(); //get the child elements
                System.out.println(node.getLength());
                for(int k=0; k<node.getLength();k++){
                    Node currentNode = node.item(i);
                    Element e = (Element)currentNode;
                    System.out.println(e.getAttribute("name"));

            }

         }
    }

My analysis: The NodeList list has a length of 2. Is that true given that the XML has two course tag but when I assign to the the NodeList node the ChildNodes of the Element element, and checked the lenght of NodeList node, I found out it was 11 instead of 5 since the node has 5 sub nodes. My concern is, first, I want to know what is the length of this XML structure and secondly, how to retrieve the second . Thanks

Upvotes: 1

Views: 10341

Answers (1)

Boris the Spider
Boris the Spider

Reputation: 61128

I am not sure what you want to do exactly, but XPath will probably solve the issue. Here is a quick example using the XML snippet you provided:

public static void main(String[] args) throws UnsupportedEncodingException, ParserConfigurationException, SAXException, IOException, XPathExpressionException {
    final String xml = "<course name=\"AdvancedAlgorithm\">\n"
            + "    <Teacher name=\"Francis\" class=\"A\" />\n"
            + "    <Teacher name=\"John\" class=\"B\" />\n"
            + "    <Teacher name=\"Philips\" class=\"C\" />\n"
            + "    <course name=\"AlgorithmForBeginners\">\n"
            + "        <Teacher name=\"Simon\" class=\"E\" />\n"
            + "        <Teacher name=\"Joan\" class=\"F\" />\n"
            + "    </course>\n"
            + "    <Teacher name=\"Edward\" class=\"M\" />\n"
            + "</course>";
    final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes("UTF-8")));
    final XPath xPath = XPathFactory.newInstance().newXPath();
    final XPathExpression expression = xPath.compile("//course[@name='AdvancedAlgorithm']//Teacher");

    final NodeList nodeList = (NodeList) expression.evaluate(doc, XPathConstants.NODESET);

    for (int i = 0; i < nodeList.getLength(); ++i) {
        System.out.println(((Element)nodeList.item(i)).getAttribute("name"));
    }
}

Output:

Francis
John
Philips
Simon
Joan
Edward

So the Document is built however (from the String in this case) and then we create and compile an XPathExpression. This expression, //course[@name='AdvancedAlgorithm']//Teacher, means find all the "Teacher" elements in the document regardless of where they are as long as they have a course named "AdvancedAlgorithm" somewhere as a parent.

An expression //course[@name='AdvancedAlgorithm']/course will yield a single value, "AlgorithmForBeginners", as this asks for all courses that have a course with name "AdvancedAlgorithm" as a direct parent.

The expression //course[@name='AdvancedAlgorithm']/course[@name='AlgorithmForBeginners']/Teacher will find all courses named "AlgorithmForBeginners" that have a direct parent that is a course named "AdvancedAlgorithm" and list all of the Teacher elements that are direct children.

To find all teachers of any course named "AlgorithmForBeginners" you would use //course[@name='AlgorithmForBeginners']/Teacher for direct children or //course[@name='AlgorithmForBeginners']//Teacher for any child, i.e. direct or indirect.

Is that what you were looking for; I am not sure what "attribute value of the second" means.

Upvotes: 2

Related Questions