Java, XPath - how to get the entire node base for a specific element

I have the following XML structure

<students>
<student studentnumber="1">
    <firstname>Charlie</firstname>
    <lastname>Davies</lastname>
    <marks>
        <first>12</first>
        <second>52</second>
        <third>98</third>
        <forth>32</forth>
    </marks>
</student>
<student studentnumber="2">
    <firstname>Emily</firstname>
    <lastname>Roberts</lastname>
    <marks>
        <first>55</first>
        <second>51</second>
        <third>57</third>
        <forth>84</forth>
    </marks>
</student>

How can I build a query to get the name of students who have a first mark of more than 50? I do this, and I see that there is one result that I expect, but does not print anything.

    String expression = "/students/student[marks/first > 50]";
    NodeList nodes = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);

    System.out.println(nodes.getLength());

    for (int i = 0; i < nodes.getLength(); ++i) {
        System.out.println(nodes.item(i).getFirstChild().getNodeValue());
    }

Thank.

+4
source share
2 answers

you just need to just change the Xpath expression: String expression = "/students/student[marks/first > 50]/firstname/text()"

And your for-loop for:

for (int i = 0; i < nodes.getLength(); i++) {
    System.out.println(nodes.item(i).getNodeValue());
}

Conclusion:

1
Emily
+2
source

GetFirstChild () and getChildNodes () give not only children, but also text nodes. The first node you get will be the text node (just whitespace and line break).

Example:

String expression = "/students/student[marks/first > 50]";
NodeList nodes = (NodeList) 
xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);


 for (int i = 0; i < nodes.getLength(); ++i) {
        Node n = nodes.item(i);
        for (int j = 0; j < n.getChildNodes().getLength(); ++j) {
            Node n1 = n.getChildNodes().item(j);
            System.out.println("Level 1 node type: " + n1.getNodeType());
            System.out.println("Level 1 node value: " + n1.getNodeValue());
            for (int k = 0; k < n1.getChildNodes().getLength(); ++k) {
                Node n2 = n1.getChildNodes().item(k);
                System.out.println("  Level 2 node type: " + n2.getNodeType());
                System.out.println("  Level 2 Node value: " + n2.getNodeValue());
            }
        }
    }

Conclusion:

1
Level 1 node type: 3
Level 1 node value: '
    '
Level 1 node type: 1
Level 1 node value: 'null'
  Level 2 node type: 3
  Level 2 Node value: 'Emily'
Level 1 node type: 3
Level 1 node value: '
    '
Level 1 node type: 1
Level 1 node value: 'null'
  Level 2 node type: 3
  Level 2 Node value: 'Roberts'
Level 1 node type: 3
Level 1 node value: '
    '
Level 1 node type: 1
Level 1 node value: 'null'
  Level 2 node type: 3
  Level 2 Node value: '
        '
  Level 2 node type: 1
  Level 2 Node value: 'null'
  Level 2 node type: 3
  Level 2 Node value: '
        '
  Level 2 node type: 1
  Level 2 Node value: 'null'
  Level 2 node type: 3
  Level 2 Node value: '
        '
  Level 2 node type: 1
  Level 2 Node value: 'null'
  Level 2 node type: 3
  Level 2 Node value: '
        '
  Level 2 node type: 1
  Level 2 Node value: 'null'
  Level 2 node type: 3
  Level 2 Node value: '
    '
Level 1 node type: 3
Level 1 node value: '
'

EDIT: Changed example of displaying student names, not student grades

+1
source

Source: https://habr.com/ru/post/1696092/


All Articles