Java, XPath - 如何根据特定元素获取整个节点
Java, XPath - how to get the entire node base on specific element
我有以下XML结构
<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>
如何构造查询以获取第一个分数超过 50 的学生的名字?我正在这样做,我可以看到有一个结果符合我的预期,但它没有打印出任何东西。
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());
}
谢谢。
您只需简单地更改您的 Xpath 表达式即可:
String expression = "/students/student[marks/first > 50]/firstname/text()"
你的 for-loop 到:
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println(nodes.item(i).getNodeValue());
}
输出:
1
Emily
GetFirstChild() 和 getChildNodes() 不仅产生子元素节点,而且产生文本节点。您获得的第一个节点将是一个文本节点(只有空白字符和一个换行符)。
示例:
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());
}
}
}
输出:
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: '
'
编辑:将示例更改为输出学生姓名,而不是学生分数
我有以下XML结构
<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>
如何构造查询以获取第一个分数超过 50 的学生的名字?我正在这样做,我可以看到有一个结果符合我的预期,但它没有打印出任何东西。
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());
}
谢谢。
您只需简单地更改您的 Xpath 表达式即可:
String expression = "/students/student[marks/first > 50]/firstname/text()"
你的 for-loop 到:
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println(nodes.item(i).getNodeValue());
}
输出:
1
Emily
GetFirstChild() 和 getChildNodes() 不仅产生子元素节点,而且产生文本节点。您获得的第一个节点将是一个文本节点(只有空白字符和一个换行符)。
示例:
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());
}
}
}
输出:
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: '
'
编辑:将示例更改为输出学生姓名,而不是学生分数