1. 程式人生 > >JavaWeb學習筆記之XML(2)

JavaWeb學習筆記之XML(2)

文章目錄


相關知識: https://blog.csdn.net/mokexfdgh/article/category/8092196


xml的解析(jaxp)

xml的解析方式:dom和sax兩種技術
xml的解析器(針對dom和sax):jaxp,dom4j(使用最多),jdom
jaxp是JavaSe的一部分,在jdk的javax.xml.parsers包裡

dom方式解析xml

dom解析xml的過程:
dom
dom所使用的類:
 dom
  DocumentBuilder->解析器類
   此類為抽象類,例項可以從DocumentBuilderFactory.newDocumentBuilder()方法獲取
   解析xml檔案的方法:parse(“xml檔案路徑”);//返回的是Document整個文件(Document為一個介面,父節點是Node)
   getElementsByTagName(String TagName);//返回NodeList集合(getLength():集合長度,item(int index):下標獲取值)
   creatElement(String tagName);//建立標籤
   creatTexNode(String data);//建立文字
   appendChild(Node newChild);//將newNode節點新增到此節點後面
   removeChild(Node oldChild);//刪除節點
   getParentNode();//獲取父節點
   getTextContent();//得到此元素裡面的值
  DocumentBudilderFactory->解析器工廠
  此類也為抽象類,newInstance()方法

jaxp的查詢操作:

	DocumentBuilderFactory buliderFactory = DocumentBuilderFactory.newInstance();//建立解析工廠
	DocumentBuilder builder = builderFactory.newDocumentBuilder();//建立解析器
	Document document = builder.parse("src/person.xml");//解析xml檔案並返回document物件
	NodeList list = document.getElementsByTagName("name");//得到所有name元素存在NodeList
for(int i=0;i<list.getLength();i++){//遍歷陣列 Node name1 = list.item(i);//得到每一個name元素,也可以通過指定的下標獲取某一個節點 String s = name1.getTextContent();//得到name元素裡面的值 }

jaxp的新增操作:

	DocumentBuilderFactory buliderFactory = DocumentBuilderFactory.newInstance();
	DocumentBuilder builder = builderFactory.newDocumentBuilder();
	Document document = builder.parse("src/person.xml");
	NodeList list = document.getElementsByTagName("p1");
	Node p1 = list.item[0];
	Element sex1 = document.createElement("sex");
	Text text1 = document.creatTextNode("nv");
	sex1.appendChild(text1);
	p1.appendChild(sex1);
	//將記憶體中的修改回寫到xml檔案中
	TransformerFactory transformerFactory = TransformerFactory.newInstance();
	Transformer transformeer = transformerFactory.newTransformer();
	transformer.transform(new DOMSource(document),new StreamReasult("src/person.xml"));

jaxp的修改操作:

	DocumentBuilderFactory buliderFactory = DocumentBuilderFactory.newInstance();
	DocumentBuilder builder = builderFactory.newDocumentBuilder();
	Document document = builder.parse("src/person.xml");
	NodeList list = document.getElementsByTagName("sex");
	Node sex1 = list.item[0];
	sex1.setTextContent("nan");
	//將記憶體中的修改回寫到xml檔案中
	TransformerFactory transformerFactory = TransformerFactory.newInstance();
	Transformer transformeer = transformerFactory.newTransformer();
	transformer.transform(new DOMSource(document),new StreamReasult("src/person.xml"));

jaxp的刪除操作:

	DocumentBuilderFactory buliderFactory = DocumentBuilderFactory.newInstance();
	DocumentBuilder builder = builderFactory.newDocumentBuilder();
	Document document = builder.parse("src/person.xml");
	Node sex1 = document.getElementsByTagName("sex").item[0];
	Node p1 = sex1.getParentNode();//獲取sex的父節點
	p1.removeChild(sex1);//刪除sex
	TransformerFactory transformerFactory = TransformerFactory.newInstance();
	Transformer transformeer = transformerFactory.newTransformer();
	transformer.transform(new DOMSource(document),new StreamReasult("src/person.xml"));

jaxp的遍歷操作(列印所有xml的元素):

	DocumentBuilderFactory buliderFactory = DocumentBuilderFactory.newInstance();
	DocumentBuilder builder = builderFactory.newDocumentBuilder();
	Document document = builder.parse("src/person.xml");
	list1(document);
	
	private static void list1(Node node){
		if(node.getNodeType == Node.ELEMENT_NODE)//剔除空格和換行
			System.out.println(node.getNodeNmae());
		NodeList lis1 = node.getChildNodes();//得到一層子節點
		for(int i=0;i<list.getLength();i++){
			Node node1 = list.item[i];
			list1(node1);
		}
	}

sax方式解析xml

dom解析方式:根據xml的層級結構在記憶體中分配一個樹形結構,把xml中的標籤、屬性、文字封裝成物件
sax解析方式:事件驅動,邊讀邊解析
sax解析xml的過程:
在這裡插入圖片描述
dom所使用的類:
  SAXParser->解析器類
   例項通過SAXParserFactory.newSAXParser()方法獲得
   解析xml檔案方法:parse(“xml的路徑”,“事件處理器”)
  SAXParserFactory->解析器工廠
   例項通過newInstance()方法獲得

jaxp的查詢操作:
注:sax方式解析不能進行增刪改操作,只能進行查詢操作

	SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
	SAXParser saxParser = saxParserFactory.newSAXParser();
	saxParser.parse("src/p1.xml",new MyDefault1());//事件處理器傳入後,會自動執行裡面的方法
	
	//查詢操作則就是在事件處理器類中重寫三個方法實現,如下表示查詢所有name標籤的文字內容/獲取某一個
	class MyDefault2 extends DefaultHandler{
		boolean flag;
		int idx = 1;
		punlic void startElement(String uri,String localName,String qName,Attributes attributes) throws SAXException{
			//判斷是否是name標籤
			if("name".equals(qName)){
				flag = true;
			}
		}
		public void characters(char[] ch,int start,int length) throws SAXEception{
			//當flag值是true時,表示解析到name標籤,則列印此標籤下的文字內容
			if(flag == true && idx == 1){//加上idx==1則獲取到第一個name標籤的文字內容,不加即為所有name元素值
				System.out.println(new String(ch,start,length));
			}
		}
		public void endElement(String uri,String localName,String qName) throws SAXException{
			//把flag值設定成false,表示當前name標籤結束
			if("name".equals(qName)){
				flag = false;
				idx++;
			}
		}
	}
	//建立事件處理器類(繼承DefaultHandler並重寫三個用於解析的方法)
	class MyDefault1 extends DefaultHandler{
		punlic void startElement(String uri,String localName,String qName,Attributes attributes) throws SAXException{
		}
		public void characters(char[] ch,int start,int length) throws SAXEception{
			super.characters(ch,start,length);
		}
		public void endElement(String uri,String localName,String qName) throws SAXException{
		}
	}

dom4j解析器

dom4j區別於jaxp:不是javase的一部分,需要在myeclipse中匯入dom4j的jar包
包中的常用方法:
1.得到document物件(dom4j包裡的document,不同於w3c包裡的)

	SAXReader reader = new SAXReader();
	Document document = reader.read(url);

2.document,Element的父介面是Node(它們找不到方法,到Node找)

	Element root = doucment.getRootElement();//返回Element,獲取根節點
	element.getParent();//獲取父節點
	element.addElement(Node node);//新增標籤
	element(qName);//獲取標籤下的第一個子標籤
	elements(qName);//獲取標籤下一層的所有子標籤
	elements();//獲取標籤下所有的子標籤

4.dom4j的查詢操作:

	SAXReader reader = new SAXReader();//建立解析器
	Document document = reader.read("src/1.xml");//通過解析器獲取xml檔案的document物件
	Element root = doucment.getRootElement();
	List<Element> list = root.elements("p1");//獲取根節點下所有p1子標籤,並存在list中
	for(Element element : list){//遍歷list
		Element nam1 = element.element("name");//獲取每個p1標籤中的第一個name標籤
		String s = name1.getText();//得到name標籤的文字內容
		System.out.println(s);
	}

5.dom4j的新增操作:

	//在末尾新增節點
	SAXReader reader = new SAXReader();//建立解析器
	Document document = reader.read("src/1.xml");//通過解析器獲取xml檔案的document物件
	Element root = doucment.getRootElement();
	Element p1 = root.element("p1");
	Element sex1 = p1.addElment("sex");//在p1下面直接新增元素(標籤),並返回新增的元素
	sex1.setText("nan");//在sex下面新增文字
	//回寫xml
	OutputFormat format = OutputFormat.createPrettyPrint();//回寫xml的排版,有縮排的效果(createCompactFormat:沒縮排)
	XMLWriter xmlWriteer = new XMLWriter(new FileOutputStream("src/1.xml"),format);
	xmlWriter.write(document);
	xmlWriter.close();
	//在特定位置新增節點,則可以使用elements()方法獲取特定位置處的元素集合,回寫xml
	Element p1 = root.element("p1");
	List<Element> list = root.elements("p1");
	Element school = DocumentHelper.creatElement("school");//建立元素
	school.setText("ecit");//新增文字
	list.add(1,school);//在特定位置新增

6.獲取document物件和回寫的操作可以封裝成一個工具類:

	class Dom4jTool{
		public static final String Path = "src/1.xml";//封裝路徑
		public static Document getDocument(String url){//靜態方法,直接用類名呼叫
			try{
				SAXReader reader = new SAXReader();
				Document document = reader.read(url);
				return document;
			}catch(Exceptiong e){
				e.prinStackTrace();
			}
			return null;
		}
		public static void xmlWriter(Stirng path,Document document){
			try{
				OutputFormat format = OutputFormat.createPrettyPrint();
				XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/1.xml"),format);
				xmlWriter.write(document);
				xmlWriter.close();
			}catch(Exceptiong e){
				e.prinStackTrace();
			}
		}
	}

7.dom4j的修改操作:

	Document document = Dom4jTool.getDocument(Dom4jTool.Path);//呼叫工具類獲取document物件
	Element root = document.getRootElement();
	Element p1 = root.element("p1");
	Element age = p1.element("age");
	age.setText("30");//修改age值位30
	Dom4jTool.xmlWriter(Dom4jTool.Path,doucment);//呼叫工具類進行回寫

8.dom4j的刪除操作:

	Document document = Dom4jTool.getDocument(Dom4jTool.Path);
	Element root = document.getRootElement();
	Element p1 = root.element("p1");
	Element sch = p1.element("school");
	p1.remove(sch);//刪除p1下的子標籤school
	Dom4jTool.xmlWriter(Dom4jTool.Path,doucment);

9.dom4j獲取屬性值的操作:

	Document document = Dom4jTool.getDocument(Dom4jTool.Path);
	Element root = document.getRootElement();
	Element p1 = root.element("p1");
	String s = p1.attributeValue("id1");//獲取p1的屬性id1的值
	System.out.println(s);

10.dom4j中的XPATH操作
上面的操作都是一層一層的來進行操作的,XPATH可以直接獲取某個元素

表現形式:
 ①/AAA/DDD/BBB:表示獲取AAA下的DDD中的BBB元素
 ②//BBB:表示獲取所有的名為BBB元素
 ③/* :表示獲取所有的元素
 ④BBB[1]:表示獲取第一個BBB元素->BBB[last()]:表示獲取最後一個BBB元素
 ⑤//BBB[@id]:表示獲取所有有id屬性的BBB元素
 ⑥//BBB[@id=‘b1’]:表示獲取有id屬性值為b1的BBB

具體操作:
dom4j本身不支援xpath,但提供了兩個使用xpath的方法,且需要引入支援xpath的jar包(jaxen-1.1-beta-6.jar)
兩個方法:
 ·selectNodes(“xpath表示式”)//獲取多個節點
 ·selectSingleNode(“xpath表示式”)//獲取一個節點

使用xpath實現查詢xml中所有name元素的值:

	Document document = Dom4jTool.getDocument(Dom4jTool.Path);
	List<Node> list = document.selectNodes("//name");
	for(Node node : list){
		String s = node.getText();
		System.out.println(s);
	}

使用xpath實現獲取第一個p1下面的name的值:

	Document document = Dom4jTool.getDocument(Dom4jTool.Path);
	Node name1 = document.selectSingleNodes("//p1[@id1='aaaa']/name");
	String s1 = name1.getText();
	System.out.println(s);