XPath解析xml总结

什么是XPath?

  • XPath使用路径表达式在XML文档中进行导航
  • XPath包含一个标准函数库
  • XPath是 XSLT 中的主要元素
  • XPath是一个 W3C 标准

XPath路径表达式
XPath使用路径表达式来选取XML文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。

 

XPath标准函数
XPath含有超过100个内建的函数。这些函数用于字符串值、数值、日期和时间比较、节点和QName处理、序列处理、逻辑值等等。

 

在XPath中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档节点(或称为根节点)。

 

XPath使用路径表达式来选取XML文档中的节点或节点集。节点是通过沿着路径(path)或者步(steps)来选取的。

 

 

使用XPath的解析XML的工具类

好吧,这还是09年底写的,会不会太老旧了?

 

Java代码   收藏代码
  1. import java.io.File;  
  2. import java.io.IOException;  
  3. import java.io.InputStream;  
  4. import javax.xml.parsers.DocumentBuilder;  
  5. import javax.xml.parsers.DocumentBuilderFactory;  
  6. import javax.xml.parsers.ParserConfigurationException;  
  7. import javax.xml.xpath.XPath;  
  8. import javax.xml.xpath.XPathConstants;  
  9. import javax.xml.xpath.XPathExpression;  
  10. import javax.xml.xpath.XPathExpressionException;  
  11. import javax.xml.xpath.XPathFactory;  
  12. import org.w3c.dom.Document;  
  13. import org.w3c.dom.Node;  
  14. import org.w3c.dom.NodeList;  
  15. import org.xml.sax.SAXException;  
  16.   
  17. /** 
  18.  * 解析XML的工具类,使用XPath 
  19.  *  
  20.  * @author ChenFeng 
  21.  * @version [版本号, 2009-12-22] 
  22.  * @see [相关类/方法] 
  23.  * @since [产品/模块版本] 
  24.  */  
  25. public class XMLParseUtil {  
  26.     private DocumentBuilder builder;  
  27.   
  28.     private XPath xpath;  
  29.   
  30.     /** 
  31.      * 默认构造函数 
  32.      *  
  33.      * @throws ParserConfigurationException 
  34.      *             创建XML解析器出错! 
  35.      */  
  36.     public XMLParseUtil() throws ParserConfigurationException {  
  37.         DocumentBuilderFactory domfactory = DocumentBuilderFactory  
  38.                 .newInstance();  
  39.         builder = domfactory.newDocumentBuilder();  
  40.   
  41.         XPathFactory xpfactory = XPathFactory.newInstance();  
  42.         xpath = xpfactory.newXPath();  
  43.     }  
  44.   
  45.     /** 
  46.      * 根据路径解析XML文档 
  47.      *  
  48.      * <pre> 
  49.      * 可能产生而没有显式抛出的异常: 
  50.      * 1) MalformedURLException :传入文件路径错误!找不到要解析的文件! 
  51.      * 2) SAXParseException : 文件格式错误!无法解析! 
  52.      * </pre> 
  53.      *  
  54.      * @param path 
  55.      *            文件路径 
  56.      * @return Document对象 
  57.      * @throws IOException 
  58.      *             IO异常 
  59.      * @throws SAXException 
  60.      *             SAX异常 
  61.      * @see [类、类#方法、类#成员] 
  62.      */  
  63.     public Document parseDocument(String path) throws IOException, SAXException {  
  64.         return builder.parse(path);  
  65.     }  
  66.   
  67.     /** 
  68.      * 根据文件解析XML文档 
  69.      *  
  70.      * <pre> 
  71.      * 可能产生而没有显式抛出的异常: 
  72.      * 1) IllegalArgumentException :传入参数错误!如对象不能为空! 
  73.      * 2) SAXParseException : 文件格式错误!无法解析! 
  74.      * </pre> 
  75.      *  
  76.      * @param file 
  77.      *            文件 
  78.      * @return Document对象 
  79.      * @throws IOException 
  80.      *             IO异常 
  81.      * @throws SAXException 
  82.      *             SAX异常 
  83.      * @see [类、类#方法、类#成员] 
  84.      */  
  85.     public Document parseDocument(File file) throws IOException, SAXException {  
  86.         return builder.parse(file);  
  87.     }  
  88.   
  89.     /** 
  90.      * 根据输入流解析XML文档 
  91.      *  
  92.      * <pre> 
  93.      * 可能产生而没有显式抛出的异常: 
  94.      * 1) IllegalArgumentException :传入参数错误!如对象不能为空! 
  95.      * 2) SAXParseException : 文件格式错误!无法解析! 
  96.      * </pre> 
  97.      *  
  98.      * @param is 
  99.      *            输入流 
  100.      * @return Document对象 
  101.      * @throws IOException 
  102.      *             IO异常 
  103.      * @throws SAXException 
  104.      *             SAX异常 
  105.      * @see [类、类#方法、类#成员] 
  106.      */  
  107.     public Document parseDocument(InputStream is) throws IOException,  
  108.             SAXException {  
  109.         return builder.parse(is);  
  110.     }  
  111.   
  112.     /** 
  113.      * 通过xpath取得节点列表 
  114.      *  
  115.      * @param node 
  116.      *            节点 
  117.      * @param expression 
  118.      *            XPath表达式 
  119.      * @return NodeList 
  120.      * @throws XPathExpressionException 
  121.      *             XPath表达式异常 
  122.      * @see [类、类#方法、类#成员] 
  123.      */  
  124.     public NodeList selectNodes(Node node, String expression)  
  125.             throws XPathExpressionException {  
  126.         // XPath对象编译XPath表达式  
  127.         XPathExpression xpexpreesion = this.xpath.compile(expression);  
  128.         Object object = xpexpreesion.evaluate(node, XPathConstants.NODESET);  
  129.         return (NodeList) object;  
  130.     }  
  131.   
  132.     /** 
  133.      * 通过xpath取得单个节点 
  134.      *  
  135.      * @param node 
  136.      *            节点 
  137.      * @param expression 
  138.      *            XPath表达式 
  139.      * @return Node 
  140.      * @throws XPathExpressionException 
  141.      *             XPath表达式异常 
  142.      * @see [类、类#方法、类#成员] 
  143.      */  
  144.     public Node selectSingleNode(Node node, String expression)  
  145.             throws XPathExpressionException {  
  146.         XPathExpression xpexpreesion = this.xpath.compile(expression);  
  147.         Object object = xpexpreesion.evaluate(node, XPathConstants.NODE);  
  148.         return (Node) object;  
  149.     }  
  150.   
  151.     /** 
  152.      * 根据xpath取得节点的文本值 
  153.      *  
  154.      * @param node 
  155.      *            节点 
  156.      * @param expression 
  157.      *            XPath表达式 
  158.      * @return String 
  159.      * @throws XPathExpressionException 
  160.      *             XPath表达式异常 
  161.      * @see [类、类#方法、类#成员] 
  162.      */  
  163.     public String getNodeStringValue(Node node, String expression)  
  164.             throws XPathExpressionException {  
  165.         XPathExpression xpexpreesion = this.xpath.compile(expression);  
  166.         Object object = xpexpreesion.evaluate(node, XPathConstants.STRING);  
  167.         return (String) object;  
  168.     }  
  169. }  

 

通过一个测试类展示工具类的使用

只是用于测试,此种写法不适用于实际项目中

Java代码   收藏代码
  1. import java.io.IOException;  
  2. import java.net.MalformedURLException;  
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import javax.xml.parsers.ParserConfigurationException;  
  7. import javax.xml.xpath.XPathExpressionException;  
  8.   
  9. import org.w3c.dom.Document;  
  10. import org.w3c.dom.Node;  
  11. import org.w3c.dom.NodeList;  
  12. import org.xml.sax.SAXException;  
  13. import org.xml.sax.SAXParseException;  
  14.   
  15. /** 
  16.  * 入口程序 
  17.  *  
  18.  * @author ChenFeng 
  19.  * @version [版本号, 2009-12-21] 
  20.  * @see [相关类/方法] 
  21.  * @since [产品/模块版本] 
  22.  */  
  23. public class XMLParseUtilTest {  
  24.   
  25.     /** 
  26.      * 入口函数 
  27.      *  
  28.      * @param args 
  29.      * @see [类、类#方法、类#成员] 
  30.      */  
  31.     public static void main(String[] args) {  
  32.         String path = XMLParseUtilTest.class.getResource("bookstore.xml")  
  33.                 .getPath();  
  34.   
  35.         XMLParseUtil xmlParse = null;  
  36.         try {  
  37.             xmlParse = new XMLParseUtil();  
  38.         } catch (ParserConfigurationException e) {  
  39.             System.out.println("异常:创建XML解析器过程中有一个严重的配置错误!");  
  40.             e.printStackTrace();  
  41.         }  
  42.         if (null != xmlParse) {  
  43.             Document doc = null;  
  44.             try {  
  45.                 doc = xmlParse.parseDocument(path);  
  46.             } catch (MalformedURLException e) {  
  47.                 System.out.println("异常:传入文件路径错误!找不到要解析的文件!");  
  48.                 e.printStackTrace();  
  49.             } catch (SAXParseException e) {  
  50.                 System.out.println("异常:文件格式错误!无法解析!");  
  51.                 e.printStackTrace();  
  52.             } catch (IOException e) {  
  53.                 e.printStackTrace();  
  54.             } catch (SAXException e) {  
  55.                 e.printStackTrace();  
  56.             }  
  57.   
  58.             if (null != doc) {  
  59.                 NodeList bookNodeList = null;  
  60.                 try {  
  61.                     /** 
  62.                      * [title/@lang='en']表示选取的book节点,必须满足子节点title的lang属性为en 
  63.                      */  
  64.                     bookNodeList = (NodeList) xmlParse.selectNodes(doc,  
  65.                             "//bookstore/book[title/@lang='en']");  
  66.                 } catch (XPathExpressionException e) {  
  67.                     System.out.println("异常:XPath表达式错误!");  
  68.                     e.printStackTrace();  
  69.                 }  
  70.   
  71.                 if (null != bookNodeList) {  
  72.                     List<Book> bookList = new ArrayList<Book>();  
  73.   
  74.                     for (int i = 0; i < bookNodeList.getLength(); i++) {  
  75.                         Node node = bookNodeList.item(i);  
  76.                         Book book = parseBookNode(xmlParse, node);  
  77.                         bookList.add(book);  
  78.                     }  
  79.   
  80.                     for (Book book : bookList) {  
  81.                         System.out.println(book.toString());  
  82.                     }  
  83.                 }  
  84.             }  
  85.         }  
  86.     }  
  87.   
  88.     /** 
  89.      * 解析单个book节点 
  90.      *  
  91.      * @param util 
  92.      * @param node 
  93.      * @return 
  94.      * @throws XPathExpressionException 
  95.      * @see [类、类#方法、类#成员] 
  96.      */  
  97.     public static Book parseBookNode(XMLParseUtil util, Node node) {  
  98.         String lang = "";  
  99.         String title = "";  
  100.         String author = "";  
  101.         String year = "";  
  102.         String price = "";  
  103.   
  104.         try {  
  105.             title = util.getNodeStringValue(node, "./title");  
  106.         } catch (XPathExpressionException e) {  
  107.             System.out.println("异常:XPath表达式错误!");  
  108.             e.printStackTrace();  
  109.         }  
  110.         try {  
  111.             lang = util.getNodeStringValue(node, "./title/@lang");  
  112.         } catch (XPathExpressionException e) {  
  113.             System.out.println("异常:XPath表达式错误!");  
  114.             e.printStackTrace();  
  115.         }  
  116.         try {  
  117.             author = util.getNodeStringValue(node, "./author");  
  118.         } catch (XPathExpressionException e) {  
  119.             System.out.println("异常:XPath表达式错误!");  
  120.             e.printStackTrace();  
  121.         }  
  122.         try {  
  123.             year = util.getNodeStringValue(node, "./year");  
  124.         } catch (XPathExpressionException e) {  
  125.             System.out.println("异常:XPath表达式错误!");  
  126.             e.printStackTrace();  
  127.         }  
  128.         try {  
  129.             price = util.getNodeStringValue(node, "./price");  
  130.         } catch (XPathExpressionException e) {  
  131.             System.out.println("异常:XPath表达式错误!");  
  132.             e.printStackTrace();  
  133.         }  
  134.   
  135.         Book book = new Book(lang, title, author, year, price);  
  136.         return book;  
  137.     }  
  138.   
  139. }  

 

 

上面的测试类所使用的XML文件

文件名      :  bookstore.xml

文件路径  :  与上面的两个类放到同一目录下

Xml代码   收藏代码
  1. <?xml version="1.0" encoding="gbk"?>  
  2. <bookstore>  
  3.     <book>  
  4.         <title lang="en">Harry Potter</title>  
  5.         <author>J K. Rowling</author>  
  6.         <year>2005</year>  
  7.         <price>28.5</price>  
  8.     </book>  
  9.     <book>  
  10.         <title lang="en">Junit IN Action</title>  
  11.         <author>Robert J.</author>  
  12.         <year>2007</year>  
  13.         <price>58.5</price>  
  14.     </book>  
  15.     <book>  
  16.         <title lang="en">Struts 2 IN Action</title>  
  17.         <author>Rhodes K.R</author>  
  18.         <year>2005</year>  
  19.         <price>53.6</price>  
  20.     </book>  
  21.     <book>  
  22.         <title lang="en">Thinking of Java 4th</title>  
  23.         <author>Bruce Eckel</author>  
  24.         <year>2007</year>  
  25.         <price>78.9</price>  
  26.     </book>  
  27.     <book>  
  28.         <title lang="zh">修炼架构师之道</title>  
  29.         <author>陈杰驰</author>  
  30.         <year>2009</year>  
  31.         <price>63.5</price>  
  32.     </book>  
  33.     <book>  
  34.         <title lang="zh">哲学:心灵,宇宙</title>  
  35.         <author>ChenFeng</author>  
  36.         <year>2010</year>  
  37.         <price>96</price>  
  38.     </book>  
  39. </bookstore>  

 

适用于项目中的写法(XML Node→Object)

解析一个XML节点,直接转换为一个对象并返回给调用者

 

解析XML返回对象的封装类

...

Java代码   收藏代码
  1. import java.io.File;  
  2. import java.io.IOException;  
  3.   
  4. import javax.xml.parsers.ParserConfigurationException;  
  5. import javax.xml.xpath.XPathExpressionException;  
  6.   
  7. import org.w3c.dom.Document;  
  8. import org.w3c.dom.Node;  
  9. import org.xml.sax.SAXException;  
  10. import org.xml.sax.SAXParseException;  
  11.   
  12. import cn.chenfeng.common.ServiceException;  
  13.   
  14. public class XMLParseManager {  
  15.     private XMLParseUtil xmlParser;  
  16.   
  17.     public XMLParseManager() {  
  18.         try {  
  19.             xmlParser = new XMLParseUtil();  
  20.         } catch (ParserConfigurationException e) {  
  21.             throw new ServiceException("XMLParseManager@XMLParseManager(): "  
  22.                     + "Failed to create XML parser!" + e);  
  23.         }  
  24.     }  
  25.   
  26.     /** 
  27.      * 初始化方法,通过文件对象初始化XML解析器和文档对象 
  28.      *  
  29.      * @param xmlParser 
  30.      * @param document 
  31.      * @param file 
  32.      * @see [类、类#方法、类#成员] 
  33.      */  
  34.     private Document getDocument(File file) {  
  35.         Document document = null;  
  36.         try {  
  37.             document = xmlParser.parseDocument(file);  
  38.         } catch (IllegalArgumentException e) {  
  39.             throw new ServiceException("XMLParseManager@getDocument: "  
  40.                     + "An illegal or inappropriate argument!" + e);  
  41.         } catch (SAXParseException e) {  
  42.             throw new ServiceException("XMLParseManager@getDocument: "  
  43.                     + "XML file error, can not parse!" + e);  
  44.         } catch (SAXException e) {  
  45.             throw new ServiceException("XMLParseManager@getDocument: "  
  46.                     + "There is a SAXException!" + e);  
  47.         } catch (IOException e) {  
  48.             throw new ServiceException("XMLParseManager@getDocument: "  
  49.                     + "There is an IOException!" + e);  
  50.         }  
  51.   
  52.         return document;  
  53.     }  
  54.   
  55.     /** 
  56.      * 获取节点的值 
  57.      *  
  58.      * @return nodeValue 
  59.      * @see [类、类#方法、类#成员] 
  60.      */  
  61.     private String getNodeValue(Node node, String xpath) {  
  62.         String nodeValue = null;  
  63.         try {  
  64.             nodeValue = xmlParser.getNodeStringValue(node, xpath);  
  65.         } catch (XPathExpressionException e) {  
  66.             throw new ServiceException("XMLParseManager@getNodeValue: "  
  67.                     + "XPath expression [" + xpath + "] error!" + e);  
  68.         }  
  69.         return nodeValue;  
  70.     }  
  71.   
  72.     /** 
  73.      * 根据作者姓名获取书籍 
  74.      *  
  75.      * @param file 
  76.      *            XML文件对象 
  77.      * @param name 
  78.      *            书籍作者姓名 
  79.      * @return myBook 
  80.      * @see [类、类#方法、类#成员] 
  81.      */  
  82.     public Book getBookByAuthor(File file, String name) {  
  83.         Book myBook = null;  
  84.   
  85.         if (null != file) {  
  86.             Document doc = getDocument(file);  
  87.             if (null != doc) {  
  88.                 /* 
  89.                  * [author='" + name + "'] 表示只取author为name参数值的book节点 
  90.                  */  
  91.                 String title = getNodeValue(doc, "//book[author='" + name  
  92.                         + "']/title");  
  93.                 String lang = getNodeValue(doc, "//book[author='" + name  
  94.                         + "']/title/@lang");  
  95.                 String author = getNodeValue(doc, "//book[author='" + name  
  96.                         + "']/author");  
  97.                 String year = getNodeValue(doc, "//book[author='" + name  
  98.                         + "']/year");  
  99.                 String price = getNodeValue(doc, "//book[author='" + name  
  100.                         + "']/price");  
  101.                 myBook = new Book(lang, title, author, year, price);  
  102.             }  
  103.         } else {  
  104.             throw new ServiceException("XMLParseManager@getBookByAuthor: "  
  105.                     + "File is null!");  
  106.         }  
  107.   
  108.         return myBook;  
  109.     }  
  110.   
  111. }  

 

 

上面类的单元测试类

...

Java代码   收藏代码
  1. import java.io.File;  
  2.   
  3. import org.junit.After;  
  4. import org.junit.Assert;  
  5. import org.junit.Before;  
  6. import org.junit.Test;  
  7.   
  8. public class XMLParseManagerTest {  
  9.     XMLParseManager xmlMgr;  
  10.   
  11.     @Before  
  12.     public void setUp() throws Exception {  
  13.         xmlMgr = new XMLParseManager();  
  14.     }  
  15.   
  16.     @After  
  17.     public void tearDown() throws Exception {  
  18.     }  
  19.   
  20.     @Test  
  21.     public void testGetMyBook() {  
  22.         String path = XMLParseManager.class.getResource("bookstore.xml")  
  23.                 .getPath();  
  24.         File xmlfile = new File(path);  
  25.         Book actualBook = xmlMgr.getBookByAuthor(xmlfile, "ChenFeng");  
  26.         Assert.assertNotNull(actualBook);  
  27.   
  28.         Book expectedBook = new Book("zh", "哲学:心灵,宇宙", "ChenFeng", 2010, 96.0);  
  29.         Assert.assertEquals(expectedBook, actualBook);  
  30.     }  
  31. }  

 

使用到的Bean类

...

Java代码   收藏代码
    1. package cn.chenfeng.XML.xpath;  
    2.   
    3. /** 
    4.  * Book类 
    5.  *  
    6.  * @author ChenFeng 
    7.  * @version [版本号, 2009-12-21] 
    8.  * @see [相关类/方法] 
    9.  * @since [产品/模块版本] 
    10.  */  
    11. public class Book {  
    12.     private String lang;  
    13.   
    14.     private String title;  
    15.   
    16.     private String author;  
    17.   
    18.     private int year;  
    19.   
    20.     private double price;  
    21.   
    22.     public Book() {  
    23.     }  
    24.   
    25.     public Book(String lang, String title, String author, String year,  
    26.             String price) {  
    27.         this.lang = lang;  
    28.         this.title = title;  
    29.         this.author = author;  
    30.         this.year = (int) Integer.valueOf(year);  
    31.         this.price = (double) Double.valueOf(price);  
    32.     }  
    33.   
    34.     public Book(String lang, String title, String author, int year, double price) {  
    35.         this.lang = lang;  
    36.         this.title = title;  
    37.         this.author = author;  
    38.         this.year = year;  
    39.         this.price = price;  
    40.     }  
    41.   
    42.     public String getLang() {  
    43.         return lang;  
    44.     }  
    45.   
    46.     public void setLang(String lang) {  
    47.         this.lang = lang;  
    48.     }  
    49.   
    50.     public String getTitle() {  
    51.         return title;  
    52.     }  
    53.   
    54.     public void setTitle(String title) {  
    55.         this.title = title;  
    56.     }  
    57.   
    58.     public String getAuthor() {  
    59.         return author;  
    60.     }  
    61.   
    62.     public void setAuthor(String author) {  
    63.         this.author = author;  
    64.     }  
    65.   
    66.     public int getYear() {  
    67.         return year;  
    68.     }  
    69.   
    70.     public void setYear(String year) {  
    71.         this.year = (int) Integer.valueOf(year);  
    72.     }  
    73.   
    74.     public void setYear(int year) {  
    75.         this.year = year;  
    76.     }  
    77.   
    78.     public double getPrice() {  
    79.         return price;  
    80.     }  
    81.   
    82.     public void setPrice(String price) {  
    83.         this.price = (double) Double.valueOf(price);  
    84.     }  
    85.   
    86.     public void setPrice(double price) {  
    87.         this.price = price;  
    88.     }  
    89.   
    90.     public boolean equals(Object object) {  
    91.         Book b = (Book) object;  
    92.         if (this.lang.equals(b.getLang()) && this.title.equals(b.getTitle())  
    93.                 && this.author.equals(b.getAuthor())  
    94.                 && this.year == b.getYear() && this.price == b.price) {  
    95.             return true;  
    96.         }  
    97.         return false;  
    98.     }  
    99.   
    100.     public String toString() {  
    101.         StringBuffer buf = new StringBuffer("");  
    102.         buf.append("Book{\n").append("  lang=").append(lang)  
    103.                 .append("\n  title=").append(title).append("\n  author=")  
    104.                 .append(author).append("\n  year=").append(year)  
    105.                 .append("\n  price=").append(price).append("\n}");  
    106.         return buf.toString();  
    107.     }  

转载于:https://www.cnblogs.com/xgwtzg/p/6141477.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值