title: xml的解析
tags:
grammar_cjkRuby: true
解析xml有三種方法
1.原生的dom解析,這個方法不常用。
2.dom4j開源庫,還可以加上jaxen-1.1的jar包,適合xPath解析表達式。能讀能寫
3.sax解析,這個適合大體積的文件,缺點是只能解析,而且只能順序讀。
dom4j的主要api:
讀取xml文檔
SAXReader reader = new SAXReader();
InputStream in = Object.class.getResourceAsStream("/test.properties");
Document doc = reader.read(in);
或者
Document doc = reader.read(new File("./src/contact.xml"));
doc.read();//可以讀取file,inputstream等
//節點:
Iterator Element.nodeIterator(); //獲取當前標簽節點下的所有子節點
//標簽:
Element Document.getRootElement(); //獲取xml文檔的根標簽
Element ELement.element("標簽名") //指定名稱的第一個子標簽
Iterator<Element> Element.elementIterator("標簽名");// 指定名稱的所有子標簽
List<Element> Element.elements(); //獲取所有子標簽
//屬性:
String Element.attributeValue("屬性名") //獲取指定名稱的屬性值
Attribute Element.attribute("屬性名");//獲取指定名稱的屬性對象
Attribute.getName() //獲取屬性名稱
Attibute.getValue() //獲取屬性值
List<Attribute> Element.attributes(); //獲取所有屬性對象
Iterator<Attribute> Element.attibuteIterator(); //獲取所有屬性對象
//文本:
Element.getText(); //獲取當前標簽的文本
Element.elementText("標簽名") //獲取當前標簽的指定名稱的子標簽的文本內容
// 使用xpath方法
List<Node> selectNodes("xpath表達式"); 查詢多個節點對象
Node selectSingleNode("xpath表達式"); 查詢一個節點對象
修改文件
2.1 寫出內容到xml文檔
XMLWriter writer = new XMLWriter(OutputStream, OutputForamt)
wirter.write(Document);
2.2 修改xml文檔的API
增加:
DocumentHelper.createDocument() 增加文檔
addElement("名稱") 增加標簽
addAttribute("名稱",“值”) 增加屬性
修改:
Attribute.setValue("值") 修改屬性值
Element.addAtribute("同名的屬性名","值") 修改同名的屬性值
Element.setText("內容") 修改文本內容
刪除
Element.detach(); 刪除標簽
Attribute.detach(); 刪除屬性
下面是一些實例代碼:
讀取文件內容
package gz.itcast.a_dom4j_read;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
/**
* 第二個dom4j讀取xml文件內容
* 節點
* 標簽
* 屬性
* 文本
* @author APPle
*
*/
public class Demo2 {
/**
* 得到節點信息
*/
@Test
public void test1() throws Exception{
//1.讀取xml文檔,返回Document對象
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("./src/contact.xml"));
//2.nodeIterator: 得到當前節點下的所有子節點對象(不包含孫以下的節點)
Iterator<Node> it = doc.nodeIterator();
while(it.hasNext()){//判斷是否有下一個元素
Node node = it.next();//取出元素
String name = node.getName();//得到節點名稱
//System.out.println(name);
//System.out.println(node.getClass());
//繼續取出其下面的子節點
//只有標簽節點才有子節點
//判斷當前節點是否是標簽節點
if(node instanceof Element){
Element elem = (Element)node;
Iterator<Node> it2 = elem.nodeIterator();
while(it2.hasNext()){
Node n2 = it2.next();
System.out.println(n2.getName());
}
}
}
}
/**
* 遍歷xml文檔的所有節點
* @throws Exception
*/
@Test
public void test2() throws Exception{
//1.讀取xml文檔,返回Document對象
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("./src/contact.xml"));
//得到根標簽
Element rooElem = doc.getRootElement();
getChildNodes(rooElem);
}
/**
* 獲取 傳入的標簽下的所有子節點
* @param elem
*/
private void getChildNodes(Element elem){
System.out.println(elem.getName());
//得到子節點
Iterator<Node> it = elem.nodeIterator();
while(it.hasNext()){
Node node = it.next();
//1.判斷是否是標簽節點
if(node instanceof Element){
Element el = (Element)node;
//遞歸
getChildNodes(el);
}
};
}
/**
* 獲取標簽
*/
@Test
public void test3() throws Exception{
//1.讀取xml文檔,返回Document對象
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("./src/contact.xml"));
//2.得到根標簽
Element rootElem = doc.getRootElement();
//得到標簽名稱
String name = rootElem.getName();
System.out.println(name);
//3.得到當前標簽下指定名稱的第一個子標簽
/*
Element contactElem = rootElem.element("contact");
System.out.println(contactElem.getName());
*/
//4.得到當前標簽下指定名稱的所有子標簽
/*
Iterator<Element> it = rootElem.elementIterator("contact");
while(it.hasNext()){
Element elem = it.next();
System.out.println(elem.getName());
}
*/
//5.得到當前標簽下的的所有子標簽
List<Element> list = rootElem.elements();
//遍歷List的方法
//1)傳統for循環 2)增強for循環 3)迭代器
/*for(int i=0;i<list.size();i++){
Element e = list.get(i);
System.out.println(e.getName());
}*/
/* for(Element e:list){
System.out.println(e.getName());
}*/
/*
Iterator<Element> it = list.iterator(); //ctrl+2 松開 l
while(it.hasNext()){
Element elem = it.next();
System.out.println(elem.getName());
}*/
//獲取更深層次的標簽(方法只能一層層地獲取)
Element nameElem = doc.getRootElement().
element("contact").element("name");
System.out.println(nameElem.getName());
}
/**
* 獲取屬性
*/
@Test
public void test4() throws Exception{
//1.讀取xml文檔,返回Document對象
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("./src/contact.xml"));
//獲取屬性:(先獲的屬性所在的標簽對象,然后才能獲取屬性)
//1.得到標簽對象
Element contactElem = doc.getRootElement().element("contact");
//2.得到屬性
//2.1 得到指定名稱的屬性值
/*
String idValue = contactElem.attributeValue("id");
System.out.println(idValue);
*/
//2.2 得到指定屬性名稱的屬性對象
/*Attribute idAttr = contactElem.attribute("id");
//getName: 屬性名稱 getValue:屬性值
System.out.println(idAttr.getName() +"=" + idAttr.getValue());*/
//2.3 得到所有屬性對象,返回LIst集合
/*List<Attribute> list = contactElem.attributes();
//遍歷屬性
for (Attribute attr : list) {
System.out.println(attr.getName()+"="+attr.getValue());
}*/
//2.4 得到所有屬性對象,返回迭代器
Iterator<Attribute> it = contactElem.attributeIterator();
while(it.hasNext()){
Attribute attr = it.next();
System.out.println(attr.getName()+"="+attr.getValue());
}
}
/**
* 獲取文本
*/
@Test
public void test5() throws Exception{
//1.讀取xml文檔,返回Document對象
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("./src/contact.xml"));
/**
* 注意: 空格和換行也是xml的內容
*/
String content = doc.getRootElement().getText();
System.out.println(content);
//獲取文本(先獲取標簽,再獲取標簽上的文本)
Element nameELem =
doc.getRootElement().element("contact").element("name");
//1. 得到文本
String text = nameELem.getText();
System.out.println(text);
//2. 得到指定子標簽名的文本內容
String text2 =
doc.getRootElement().element("contact").elementText("phone");
System.out.println(text2);
}
}
第二個練習例子
package gz.itcast.a_dom4j_read;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.Text;
import org.dom4j.io.SAXReader;
import org.junit.Test;
/**
* 練習-完整讀取xml文檔內容
* @author APPle
*
*/
public class Demo3 {
@Test
public void test() throws Exception{
//讀取xml文檔
SAXReader reader = new SAXReader();
Document doc =
reader.read(new File("./src/contact.xml"));
//讀取根標簽
Element rootELem = doc.getRootElement();
StringBuffer sb = new StringBuffer();
getChildNodes(rootELem,sb);
System.out.println(sb.toString());
}
/**
* 獲取當前標簽的所有子標簽
*/
private void getChildNodes(Element elem,StringBuffer sb){
//System.out.println(elem.getName());
//開始標簽ssss
sb.append("<"+elem.getName());
//得到標簽的屬性列表
List<Attribute> attrs = elem.attributes();
if(attrs!=null){
for (Attribute attr : attrs) {
//System.out.println(attr.getName()+"="+attr.getValue());
sb.append(" "+attr.getName()+"=\""+attr.getValue()+"\"");
}
}
sb.append(">");
//得到文本
//String content = elem.getText();
//System.out.println(content);
Iterator<Node> it = elem.nodeIterator();
while(it.hasNext()){
Node node = it.next();
//標簽
if(node instanceof Element){
Element el = (Element)node;
getChildNodes(el,sb);
}
//文本
if(node instanceof Text){
Text text = (Text)node;
sb.append(text.getText());
}
}
//結束標簽
sb.append("</"+elem.getName()+">");
}
}
修改,創建xml
package gz.itcast.a_dom4j_read;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.Text;
import org.dom4j.io.SAXReader;
import org.junit.Test;
/**
* 練習-完整讀取xml文檔內容
* @author APPle
*
*/
public class Demo3 {
@Test
public void test() throws Exception{
//讀取xml文檔
SAXReader reader = new SAXReader();
Document doc =
reader.read(new File("./src/contact.xml"));
//讀取根標簽
Element rootELem = doc.getRootElement();
StringBuffer sb = new StringBuffer();
getChildNodes(rootELem,sb);
System.out.println(sb.toString());
}
/**
* 獲取當前標簽的所有子標簽
*/
private void getChildNodes(Element elem,StringBuffer sb){
//System.out.println(elem.getName());
//開始標簽ssss
sb.append("<"+elem.getName());
//得到標簽的屬性列表
List<Attribute> attrs = elem.attributes();
if(attrs!=null){
for (Attribute attr : attrs) {
//System.out.println(attr.getName()+"="+attr.getValue());
sb.append(" "+attr.getName()+"=\""+attr.getValue()+"\"");
}
}
sb.append(">");
//得到文本
//String content = elem.getText();
//System.out.println(content);
Iterator<Node> it = elem.nodeIterator();
while(it.hasNext()){
Node node = it.next();
//標簽
if(node instanceof Element){
Element el = (Element)node;
getChildNodes(el,sb);
}
//文本
if(node instanceof Text){
Text text = (Text)node;
sb.append(text.getText());
}
}
//結束標簽
sb.append("</"+elem.getName()+">");
}
}
package gz.itcast.a_dom4j_write;
import java.io.File;
import java.io.FileOutputStream;
import org.dom4j.Document;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
* 討論寫出內容到xml文檔的細節
* @author APPle
*
*/
public class Demo2 {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
Document doc = new SAXReader().read(new File("./src/contact.xml"));
//指定文件輸出的位置
FileOutputStream out = new FileOutputStream("e:/contact.xml");
/**
* 1.指定寫出的格式
*/
OutputFormat format = OutputFormat.createCompactFormat(); //緊湊的格式.去除空格換行.項目上線的時候
//OutputFormat format = OutputFormat.createPrettyPrint(); //漂亮的格式.有空格和換行.開發調試的時候
/**
* 2.指定生成的xml文檔的編碼
* 同時影響了xml文檔保存時的編碼 和 xml文檔聲明的encoding的編碼(xml解析時的編碼)
* 結論: 使用該方法生成的xml文檔避免中文亂碼問題。
*/
format.setEncoding("utf-8");
//1.創建寫出對象
XMLWriter writer = new XMLWriter(out,format);
//2.寫出對象
writer.write(doc);
//3.關閉流
writer.close();
}
}
package gz.itcast.a_dom4j_write;
import java.io.File;
import java.io.FileOutputStream;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;
/**
* 修改xml內容
* 增加:文檔,標簽 ,屬性
* 修改:屬性值,文本
* 刪除:標簽,屬性
* @author APPle
*
*/
public class Demo3 {
/**
* 增加:文檔,標簽 ,屬性
*/
@Test
public void test1() throws Exception{
/**
* 1.創建文檔
*/
Document doc = DocumentHelper.createDocument();
/**
* 2.增加標簽
*/
Element rootElem = doc.addElement("contactList");
//doc.addElement("contactList");
Element contactElem = rootElem.addElement("contact");
contactElem.addElement("name");
/**
* 3.增加屬性
*/
contactElem.addAttribute("id", "001");
contactElem.addAttribute("name", "eric");
//把修改后的Document對象寫出到xml文檔中
FileOutputStream out = new FileOutputStream("e:/contact.xml");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer = new XMLWriter(out,format);
writer.write(doc);
writer.close();
}
/**
* 修改:屬性值,文本
* @throws Exception
*/
@Test
public void test2() throws Exception{
Document doc = new SAXReader().read(new File("./src/contact.xml"));
/**
* 方案一: 修改屬性值 1.得到標簽對象 2.得到屬性對象 3.修改屬性值
*/
//1.1 得到標簽對象
/*
Element contactElem = doc.getRootElement().element("contact");
//1.2 得到屬性對象
Attribute idAttr = contactElem.attribute("id");
//1.3 修改屬性值
idAttr.setValue("003");
*/
/**
* 方案二: 修改屬性值
*/
//1.1 得到標簽對象
/*
Element contactElem = doc.getRootElement().element("contact");
//1.2 通過增加同名屬性的方法,修改屬性值
contactElem.addAttribute("id", "004");
*/
/**
* 修改文本 1.得到標簽對象 2.修改文本
*/
Element nameElem = doc.getRootElement().
element("contact").element("name");
nameElem.setText("李四");
FileOutputStream out = new FileOutputStream("e:/contact.xml");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer = new XMLWriter(out,format);
writer.write(doc);
writer.close();
}
/**
* 刪除:標簽,屬性
* @throws Exception
*/
@Test
public void test3() throws Exception{
Document doc = new SAXReader().read(new File("./src/contact.xml"));
/**
* 1.刪除標簽 1.1 得到標簽對象 1.2 刪除標簽對象
*/
// 1.1 得到標簽對象
/*
Element ageElem = doc.getRootElement().element("contact")
.element("age");
//1.2 刪除標簽對象
ageElem.detach();
//ageElem.getParent().remove(ageElem);
*/
/**
* 2.刪除屬性 2.1得到屬性對象 2.2 刪除屬性
*/
//2.1得到屬性對象
//得到第二個contact標簽
Element contactElem = (Element)doc.getRootElement().
elements().get(1);
//2.2 得到屬性對象
Attribute idAttr = contactElem.attribute("id");
//2.3 刪除屬性
idAttr.detach();
//idAttr.getParent().remove(idAttr);
FileOutputStream out = new FileOutputStream("e:/contact.xml");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer = new XMLWriter(out,format);
writer.write(doc);
writer.close();
}
}
xPath技術
package gz.itcast.b_xpath;
import java.io.File;
import java.io.FileOutputStream;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
* 第一個xpath程序
* @author APPle
*
*/
public class Demo1 {
public static void main(String[] args) throws Exception{
/**
* 需求: 刪除id值為2的學生標簽
*/
Document doc = new SAXReader().read(new File("e:/student.xml"));
//1.查詢id為2的學生標簽
//使用xpath技術
Element stuElem = (Element)doc.selectSingleNode("//Student[@id='2']");
//2.刪除標簽
stuElem.detach();
//3.寫出xml文件
FileOutputStream out = new FileOutputStream("e:/student.xml");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer = new XMLWriter(out,format);
writer.write(doc);
writer.close();
}
}
package gz.itcast.b_xpath;
import java.io.File;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
/**
* 學習xPath表達式語法
* @author APPle
*
*/
public class Demo2 {
public static void main(String[] args) throws Exception {
Document doc = new SAXReader().read(new File("./src/contact.xml"));
String xpath = "";
/**
* 1. / 絕對路徑 表示從xml的根位置開始或子元素(一個層次結構)
*/
xpath = "/contactList";
xpath = "/contactList/contact";
/**
* 2. // 相對路徑 表示不分任何層次結構的選擇元素。
*/
xpath = "//contact/name";
xpath = "//name";
/**
* 3. * 通配符 表示匹配所有元素
*/
xpath = "/contactList/*"; //根標簽contactList下的所有子標簽
xpath = "/contactList//*";//根標簽contactList下的所有標簽(不分層次結構)
/**
* 4. [] 條件 表示選擇什么條件下的元素
*/
//帶有id屬性的contact標簽
xpath = "//contact[@id]";
//第二個的contact標簽
xpath = "//contact[2]";
//選擇最后一個contact標簽
xpath = "//contact[last()]";
/**
* 5. @ 屬性 表示選擇屬性節點
*/
xpath = "//@id"; //選擇id屬性節點對象,返回的是Attribute對象
xpath = "//contact[not(@id)]";//選擇不包含id屬性的contact標簽節點
xpath = "//contact[@id='002']";//選擇id屬性值為002的contact標簽
xpath = "//contact[@id='001' and @name='eric']";//選擇id屬性值為001,且name屬性為eric的contact標簽
/**
*6. text() 表示選擇文本內容
*/
//選擇name標簽下的文本內容,返回Text對象
xpath = "//name/text()";
xpath = "//contact/name[text()='張三']";//選擇姓名為張三的name標簽
List<Node> list = doc.selectNodes(xpath);
for (Node node : list) {
System.out.println(node.toString());
}
}
}
package gz.itcast.b_xpath;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* xpath案例: 模擬用戶登錄效果
* @author APPle
*
*/
public class Demo3 {
public static void main(String[] args)throws Exception{
//1.獲取用戶輸入的用戶名和密碼
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
System.out.println("請輸入用戶名:");
String name = br.readLine();
System.out.println("請輸入密碼:");
String password = br.readLine();
//2.到“數據庫”中查詢是否有對應的用戶
//對應的用戶: 在user.xml文件中找到一個
//name屬性值為‘用戶輸入’,且password屬性值為‘用戶輸入’的user標簽
Document doc = new SAXReader().read(new File("./src/user.xml"));
Element userElem = (Element)doc.selectSingleNode("//user[@name='" +name +"' and @password='"+password+"']");
if(userElem!=null){
//登錄成功
System.out.println("登錄成功");
}else{
//登錄失敗
System.out.println("登錄失敗");
}
}
}
package gz.itcast.b_xpath;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
- 使用xpath技術讀取一個規范的html文檔
- @author APPle
*/
public class Demo4 {
public static void main(String[] args) throws Exception{
Document doc = new SAXReader().read(new File("./src/personList.html"));
//System.out.println(doc);
//讀取title標簽
Element titleElem = (Element)doc.selectSingleNode("//title");
String title = titleElem.getText();
System.out.println(title);
/**
* 練習:讀取聯系人的所有信息
* 按照以下格式輸出:
* 編號:001 姓名:張三 性別:男 年齡:18 地址:xxxx 電話: xxxx
* 編號:002 姓名:李四 性別:女 年齡:20 地址:xxxx 電話: xxxx
* ......
*/
//1.讀取出所有tbody中的tr標簽
List<Element> list = (List<Element>)doc.selectNodes("//tbody/tr");
//2.遍歷
for (Element elem : list) {
//編號
//String id = ((Element)elem.elements().get(0)).getText();
String id = elem.selectSingleNode("td[1]").getText();
//姓名
String name = ((Element)elem.elements().get(1)).getText();
//性別
String gender = ((Element)elem.elements().get(2)).getText();
//年齡
String age = ((Element)elem.elements().get(3)).getText();
//地址
String address = ((Element)elem.elements().get(4)).getText();
//電話
String phone = ((Element)elem.elements().get(5)).getText();
System.out.println("編號:"+id+"\t姓名:"+name+"\t性別:"+
gender+"\t年齡:"+
age+"\t地址:"+address+
"\t電話:"+phone);
}
}
}