使用XPath获取已选中节点的子节点
有如下的一个XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<Students>
<Student id="001" grade="C">
<Age>16</Age>
<Name>phoebe</Name>
<Address>
<Country>USA</Country>
<City>Alaska</City>
</Address>
</Student>
<Student id="002" grade="A">
<Age>18</Age>
<Name>eileen</Name>
<Address>
<Country>USA</Country>
<City>Chicago</City>
</Address>
</Student>
<Student id="003" grade="C">
<Age>15</Age>
<Name>angela</Name>
<Address>
<Country>USA</Country>
<City>Boston</City>
</Address>
</Student>
<Student id="004" grade="B">
<Age>17</Age>
<Name>mars</Name>
<Address>
<Country>CHN</Country>
<City>BeiJing</City>
</Address>
</Student>
<Student id="005" grade="C">
<Age>19</Age>
<Name>grace</Name>
<Address>
<Country>UK</Country>
<City>London</City>
</Address>
</Student>
</Students>
需要从此文件中找出grade
为C
的Student
,并输出其ID和详细信息。使用/Students/Student[@grade=\"C\"]
即可选择出满足条件的Student
:
List<Element> students = root.selectNodes("/Students/Student[@grade=\"C\"]");
if(!students.isEmpty()){
for(Element student : students){
System.out.println(student.attributeValue("id"));
}
}
然后需要从选中的Student
中再次获取其子节点,一开始我使用//Name
来选取姓名,使用selectSingleNode("//Name")
获得的结果都是第一个,再用selectNodes("//Name")
选取,看到的结果是选取了所有的Student的Name
,正确的方式应该是使用selectSingleNode(".//Name")
或直接取Name:selectSingleNode("Name")
。
完整的代码如下:
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
public class XPathXmlTest {
public static void main(String[] args) {
try {
SAXReader reader = new SAXReader();
Document document = reader.read(XPathXmlTest.class.getResourceAsStream("/Students.xml"));
Element root = document.getRootElement();
List<Element> students = root.selectNodes("/Students/Student[@grade=\"C\"]");
if(!students.isEmpty()){
Node name = null;
Node age = null;
Node country = null;
Node city = null;
String format = "%s\t%s\t%s\t%s,%s";
System.out.println(String.format(format, "ID", "Name", "Age", "City", "Country"));
for(Element student : students){
name = student.selectSingleNode("Name");
age = student.selectSingleNode("Age");
country = student.selectSingleNode("Address/Country");
city = student.selectSingleNode("Address/City");
System.out.println(String.format(format, student.attributeValue("id"), name.getText(), age.getText(), city.getText(), country.getText()));
}
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
- 程序输出:
ID | Name | Age | City,Country |
---|---|---|---|
001 | phoebe | 16 | Alaska,USA |
003 | angela | 15 | Boston,USA |
005 | grace | 19 | London,UK |
注:需要依赖dom4j
和’jaxen’
参考资料
-
XPath路径表达式
路径表达式 | 说明 |
---|---|
nodename | 选取此节点的所有子节点 |
/ | 从根节点选取 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置 |
. | 选取当前节点 |
.. | 选取当前节点的父节点 |
@ | 选取属性 |