转 XML的XPath的学习小结

现在以product.xml为例学习Xpath

product.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!-- product.xml -->
<product id="200">
 <name>UML Exam Simulator</name>
 <price>100</price>
 <topics name="UML">
  <topic id="UML_SM">
   <name>Static Modeling</name>
   <questions>100</questions>
  </topic>
  <topic id="UML_AE">
   <name>Architecture</name>
   <questions>80</questions>
  </topic>
  <topic id="UML_DM">
   <name>Dynamic Modeling</name>
   <questions>67</questions>
  </topic>
 </topics>
</product>


这里使用Dom4j来解析XML文件。需要将dom4j-full.jar 放到你的类路径下面
新建一个类Service,其内容如下:


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
 
public class Service{
    private String fileName;
 
    private Document document;
 
 public Document parse(String fileName) throws DocumentException, FileNotFoundException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new BufferedInputStream(
                 new FileInputStream(fileName)));
        return document;
 }
 private void writeDocument(String filename, Document doc) throws IOException {
  OutputFormat format = OutputFormat.createPrettyPrint();
  XMLWriter writer = new XMLWriter(new BufferedOutputStream(
           new FileOutputStream(filename)), format);
  writer.write(doc);
 }
 
 public void load(String fileName) throws InitDataException{
  this.fileName = fileName;
  
  try {
   document = parse(fileName);
  } catch (FileNotFoundException e) {
   e.printStackTrace();
   throw new InitDataException("文件没有找到",e);
  } catch (DocumentException e) {
   e.printStackTrace();
   throw new InitDataException(e);
  }
 }
 
 public void store() throws StoreException{
  try {
   writeDocument(fileName,document);
  } catch (IOException e) {
   e.printStackTrace();
   throw new StoreException(e);
   
  }
 }
 
 public void testXpath(){
 //我们以<topic id="UML_SM">这个节点为当前节点来进行学习

 Element root = document.getRootElement();
  
 Element topic1 = (Element) root.selectSingleNode("//topics/topic[position()=1]");
 
String xpath = ""; //这里是用来练习Xpath的代码
  
  List list = topic1.selectNodes(xpath);
  Iterator i = list.iterator();
  while(i.hasNext()){
   Node e = (Node)i.next();
   System.out.println(e.getName());
  }
 }

 
}


直接拷贝过来会出现一些错误,创建两个异常类StoreException,InitDataException即可。

再建一个测试类Demo,内容如下:


public class Demo {
 public static void main(String[] args) {
  Service s= new Service();
  try {
   s.load("product.xml");
  } catch (InitDataException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  s.testXpath();
 }
}


现在我们来学习Xpath表达式的13种表示方式

1。ancestor 选择当前节点的祖先(以<topic id="UML_SM">为当前节点)

测试 ancestor::topics

修改testXpath()方法中的xpath:(后面都是这样修改,就不再提了)
运行Demo。
结果:
topics

测试 ancestor::*

结果:
topics
product
null

2。ancestor-or-self 选择当前节点及其祖先(以<topic id="UML_SM">为当前节点)

测试 ancestor-or-self::topics

结果:
topics


测试 ancestor-or-self::*

结果:
topic
topics
product
null

3。 attribute 选择当前结点的属性(以<topic id="UML_SM">为当前节点)

测试 attribute::*

结果:
id


4。 child 选择当前节点的所有孩子(以<topics name="UML">为当前节点,代码自己改吧)
测试 child::*

结果:
topic
topic
topic

测试 child::topic

结果:
topic
topic
topic


5。descendant 选择当前结点的所有后代 (以<topics name="UML">为当前节点)

测试 descendant::*

结果:
topic
topic
topic
name
questions
name
questions
name
questions

测试 descendant::questions

结果:
questions
questions
questions

6。 descendant-or-self 选择当前结点及其后代 (以<topics name="UML">为当前节点)

测试descendant-or-self::*

结果:
topics
topic
topic
topic
name
questions
name
questions
name
questions

测试 descendant-or-self::questions

结果:
questions
questions
questions

7。following 选择当前节点后面的所有节点 (以<topic id="UML_SM">为当前节点)

测试 following::*

结果:
topic
name
questions
topic
name
questions

测试 following::questions

结果:
questions
questions

8。following-sibling 选择当前节点之后、与当前节点具有同一父节点(兄弟节点)的所有节点。(以<topic id="UML_SM">为当前节点)

测试 following-sibling::*

结果:
topic
topic

9。namespace 选择和当前节点属于同一名称空间的所有节点。

10。parent 选择当前节点的父节点。(以<topic id="UML_SM">为当前节点)

测试 parent::node()

结果:
topics


11。 preceding 选择当前节点之前的所有节点。(以<topic id="id="UML_DM">为当前节点)

测试 preceding::*

结果:
topic
questions
name
topic
questions
name
price
name

测试 preceding::questions

结果:
questions
questions


12。 preceding-sibling  选择当前节点之前、与当前节点具有同一父节点(兄弟节点)的所有节点。(以<topic id="id="UML_DM">为当前节点)

测试 preceding-sibling::*

结果:
topic
topic


测试 preceding-sibling::topic

结果:
topic
topic


13。 self 选择当前节点。(以<topic id="id="UML_DM">为当前节点)

测试 self::node()

结果:
topic


Xpath 简写方式
有些轴可以使用缩写形式,其中包括:
@  代替 attribute::
//  代替 descendant-or-self::node()
.  代替 self::node()
.. 代替 parent::node()
无 代替 child:: (如果 XPath 表达式没有给出节点,则默认使用这个轴)
如果是用星号(*),可以选择特定节点的所有孩子,如 topics/* 选择 topics 下的所有子节点

------------------------------分割线------------------------------
注:以上XPath表达式的灵活运用,对于遍历整个XML树及灵活的查找XML节点很有帮助。在DHTML中DOM树的操作思想很类似,JavaScript提供了相应的方法

你可能感兴趣的:(JavaScript,xml,UML)