Webservice-XML與Java(五)
處理XML一般有兩種方法,DOM和基於流。相關有很多工具,比如SAX、STAX、DOM、JDOM、DOM4J等,SAX和STAX都是基於流,前者屬於推模型,後者是拉模型,STAX為oracle公司提出基於流(stream)來處理的方式,在Java中封裝成了stax,和sax很像,在webservice中一般使用基於流的工具,基於dom的或多或少的會影響一些效率。WS中還要涉及到Java物件和XML之間的轉換,可以直接使用JDK提供的JAXB。類似的還有:XStream、Jackson、json-lib,這些框架提供了xml和json,json和java物件的轉換,根據具體的需求可選擇不同的框架
Jaxb的用法很簡單,把Java物件轉換為xml叫編排,xml轉換為Java物件叫反編排,例項如下:
package com.tgb.xml; import java.io.StringReader; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import org.junit.Test; public class TestJaxb { @Test public void test01(){ try { JAXBContext ctx = JAXBContext.newInstance(Student.class); Marshaller marshaller = ctx.createMarshaller(); Student stu = new Student(1,"這是","32",new Classroom(1,"計算機","2012")); marshaller.marshal(stu, System.out); } catch (JAXBException e) { e.printStackTrace(); } } @Test public void test02(){ try { String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><student><age>32</age><classroom><grade>2012</grade><id>1</id><name>計算機</name></classroom><id>1</id><name>這是</name></student>"; JAXBContext ctx = JAXBContext.newInstance(Student.class); Unmarshaller um = ctx.createUnmarshaller(); Student stu = (Student)um.unmarshal(new StringReader(xml)); System.out.println(stu.getName() + "," + stu.getClassroom().getName()); } catch (JAXBException e) { e.printStackTrace(); } } }
下面主要講stax操作xml的例項,首先建立一個xml文件:
<?xml version="1.0" encoding="ISO-8859-1"?> <bookstore> <book category="COOKING"> <title lang="en"> Everyday Italian </title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="WEB"> <title lang="en">XQuery Kick Start</title> <author>James McGovern</author> <author>Per Bothner</author> <author>Kurt Cagle</author> <author>James Linn</author> <author>Vaidyanathan Nagarajan</author> <year>2003</year> <price>49.99</price> </book> <book category="WEB"> <title lang="en">Learning XML</title> <author>Erik T. Ray</author> <year>2003</year> <price>39.95</price> </book> </bookstore>
基於游標的查詢:
@Test
public void test01(){
XMLInputFactory factory = XMLInputFactory.newInstance();
InputStream is = null;
is = TestStax.class.getClassLoader().getResourceAsStream("books.xml");
XMLStreamReader reader;
try {
reader = factory.createXMLStreamReader(is);
while(reader.hasNext()){
int type = reader.next();
if(type == XMLStreamConstants.START_ELEMENT){ //起始節點
System.out.println(reader.getName());
}else if(type == XMLStreamConstants.CHARACTERS){ //文字節點
System.out.println(reader.getText());
}else if(type == XMLStreamConstants.END_ELEMENT){ //結束節點
System.out.println("/" + reader.getName());
}
}
} catch (XMLStreamException e) {
e.printStackTrace();
}finally{
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
public void test02(){
XMLInputFactory factory = XMLInputFactory.newInstance();
InputStream is = null;
is = TestStax.class.getClassLoader().getResourceAsStream("books.xml");
XMLStreamReader reader;
try {
reader = factory.createXMLStreamReader(is);
while(reader.hasNext()){
int type = reader.next();
if(type == XMLStreamConstants.START_ELEMENT){
String name = reader.getName().toString();
if("book".equals(name)){
//讀取屬性名和值
System.out.println(reader.getAttributeName(0) + ":" + reader.getAttributeValue(0));
}
//獲取元素內容
if("price".equals(name)){
System.out.println(reader.getElementText() + "\n");
}
}
}
} catch (XMLStreamException e) {
e.printStackTrace();
}finally{
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
基於迭代模型查詢:
@Test
public void test03(){
XMLInputFactory factory = XMLInputFactory.newInstance();
InputStream is = null;
is = TestStax.class.getClassLoader().getResourceAsStream("books.xml");
try {
//基於迭代模型的操作方式
XMLEventReader reader = factory.createXMLEventReader(is);
int num = 0;
while(reader.hasNext()){
//通過XMLEvent來獲取是否是某種節點型別
XMLEvent event = reader.nextEvent();
if(event.isStartElement()){
//通過event.asxxx轉換節點
String name = event.asStartElement().getName().toString();
if("title".equals(name)){
System.out.println(reader.getElementText() + ":");
}
if("price".equals(name)){
System.out.println(reader.getElementText() + "\n");
}
}
num++;
}
System.out.println(num);
} catch (XMLStreamException e) {
e.printStackTrace();
}finally{
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
過濾器的使用:
@Test
public void test04(){
XMLInputFactory factory = XMLInputFactory.newInstance();
InputStream is = null;
is = TestStax.class.getClassLoader().getResourceAsStream("books.xml");
try {
//基於Filter的過濾方式,可以有效的過濾不用進行操作的節點,效率高
XMLEventReader reader = factory.createFilteredReader(factory.createXMLEventReader(is), new EventFilter() {
@Override
public boolean accept(XMLEvent event) {
if(event.isStartElement()){
String name = event.asStartElement().getName().toString();
if(name.equals("title") || name.equals("price")){
return true;
}
}
return false;
}
});
int num = 0;
while(reader.hasNext()){
XMLEvent event = reader.nextEvent();
if(event.isStartElement()){
String name = event.asStartElement().getName().toString();
if("title".equals(name)){
System.out.println(reader.getElementText() + ":");
}
if("price".equals(name)){
System.out.println(reader.getElementText() + "\n");
}
}
num++;
}
System.out.println(num);
} catch (XMLStreamException e) {
e.printStackTrace();
}finally{
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
XPath的使用:
@Test
public void test05(){
XMLInputFactory factory = XMLInputFactory.newInstance();
InputStream is = null;
try{
is = TestStax.class.getClassLoader().getResourceAsStream("books.xml");
//建立文件處理物件
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
//通過DocumentBuilder建立doc的文件物件
Document doc = db.parse(is);
//建立xpath
XPath xpath = XPathFactory.newInstance().newXPath();
//第一個引數就是xpath,第二個引數就是文件
NodeList list = (NodeList)xpath.evaluate("//book[@category='WEB']", doc, XPathConstants.NODESET);
for(int i=0;i<list.getLength();i++){
//遍歷輸出相應的結果
Element e = (Element)list.item(i);
System.out.println(e.getElementsByTagName("title").item(0).getTextContent());
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
使用XMLStreamWriter建立xml:
@Test
public void test06(){
try {
XMLStreamWriter xsw = XMLOutputFactory.newInstance().createXMLStreamWriter(System.out);
xsw.writeStartDocument("utf-8", "1.0");
xsw.writeEndDocument();
String ns = "http://www.tgb.com";
xsw.writeStartElement("prefix","person",ns);
xsw.writeStartElement(ns,"id");
xsw.writeCharacters("1");
xsw.writeEndElement();
xsw.writeEndElement();
xsw.flush();
xsw.close();
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (FactoryConfigurationError e) {
e.printStackTrace();
}
}
使用Transformer更新節點資訊:
@Test
public void test07(){
try {
InputStream is = TestStax.class.getClassLoader().getResourceAsStream("books.xml");
//建立文件處理物件
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
//通過DocumentBuilder建立doc文件物件
Document doc = db.parse(is);
//建立xpath
XPath xpath = XPathFactory.newInstance().newXPath();
Transformer tran = TransformerFactory.newInstance().newTransformer();
tran.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
tran.setOutputProperty(OutputKeys.INDENT, "yes");
//第一個引數就是xpath,第二個引數就是文件
NodeList list = (NodeList)xpath.evaluate("//book[title='Learning XML']",doc,XPathConstants.NODESET);
//獲取price節點
Element be = (Element)list.item(0);
Element e = (Element)(be.getElementsByTagName("price").item(0));
e.setTextContent("232323");
Result result = new StreamResult(System.out);
//修改源
tran.transform(new DOMSource(doc), result);
} catch (Exception e) {
e.printStackTrace();
}
}
DOM4j解析xml的一篇文章:《使用Dom4j解析XML》,總體來說還是dom4j好用些。
相關推薦
Webservice-XML與Java(五)
處理XML一般有兩種方法,DOM和基於流。相關有很多工具,比如SAX、STAX、DOM、JDOM、DOM4J等,SAX和STAX都是基於流,前者屬於推模型,後者是拉模型,STAX為oracle公司提出基於流(stream)來處理的方式,在Java中封裝成了stax,和sax很像,在webservice中一般
WPF入門教程系列十——布局之Border與ViewBox(五)
last () put prev 裝飾 wpf 背景 .text 部分 九. Border Border 是一個裝飾的控件,此控件繪制邊框及背景,在 Border 中只能有一個子控件,若要顯示多個子控件,需要將一個附加的 Panel 控件放置在父 Border 中。然後可以
Redis 設計與實現 (五)--多機數據庫的實現
緩沖 所有 moved 啟動 tin 當前 body ica red 多機數據庫的實現 一、復制 slaveof 主服務器ip地址。形成主從關系。 1、同步 從向主服務器發送sync命令。 主服務器收到sync命令執行bgsav
Git的學習與使用(五)——Git 建立倉庫
Git 建立倉庫 本章節我們將為大家介紹如何建立一個 Git 倉庫。 你可以使用一個已經存在的目錄作為Git倉庫。 git init Git 使用 git init 命令來初始化一個 Git 倉庫,Git 的很多命令都需要在 Git 的倉庫中執行,所以 git i
JavaFX學習筆記——重要理念的建立與辨析(五)
處理器註冊與定義分離 問題 看過相關教程後,我們肯定對JavaFX在事件處理上,介紹的lambda表示式以及內部類簡潔用法印象深刻。但細想後其仍有很大的侷限性。 侷限一:不適用與團
高併發處理思路與手段(五):應用限流
限流就是通過對併發訪問/請求進行限速或一個時間視窗內的請求進行限速,從而達到保護系統的目的。一般系統可以通過壓測來預估能處理的峰值,一旦達到設定的峰值閥值,則可以拒絕服務(定向錯誤頁或告知資源沒有了)、排隊或等待(例如:秒殺、評論、下單)、降級(返回預設資料)。 限流不能亂用,否則正常流量會出現一些奇怪的問
高並發處理思路與手段(五):應用限流
遇到 span 有時 固定 傳輸 數據庫的操作 png 方法 就會 限流就是通過對並發訪問/請求進行限速或一個時間窗口內的請求進行限速,從而達到保護系統的目的。一般系統可以通過壓測來預估能處理的峰值,一旦達到設定的峰值閥值,則可以拒絕服務(定向錯誤頁或告知資源沒有了)、排隊
計算機組成與設計(五)—— 加法器的優化
4-bit加法器示例 先看一下上一節得到的加法器實現,可以看出改進的地方。 不難發現整個過程是從右至左依次執行,每一個進位需要等前面的運算全完成,可以在一開始得到所有的進位嗎? 行波進位加法器(Ripple-Carry Adder,RCA) 像上面4-bit加法器這樣實現的加法器被
資料結構與演算法(五)-線性表之雙向連結串列與雙向迴圈連結串列
前言:前面介紹了迴圈連結串列,雖然迴圈連結串列可以解決單鏈表每次遍歷只能從頭結點開始,但是對於查詢某一節點的上一節點,還是頗為複雜繁瑣,所以可以在結點中加入前一個節點的引用,即雙向連結串列 一、簡介 雙向連結串列:在連結串列中,每一個節點都有對上一個節點和下一個節點的引用或指標,即從一個節點出發可以有
RabbitMQ 訊息生產與消費(五)
ConnectionFactory: 獲取連線工廠 Connection 一個連線 Channel 資料通訊通道,可傳送和接受訊息 Queue 具體訊息儲存佇列 Producer & Consumer 生產者和消費者
演算法設計與分析(五):Graph And Tree
Couples Holding Hands N couples sit in 2N seats arranged in a row and want to hold hands. We want to know the minimum number of swa
0x11軟考|網路工程師經驗分享之網路互聯與網際網路(五)
目錄 一、路由器技術NAT 二、路由器技術VLSM和CIDR 三、路由器技術QoS 四、路由器技術MPLS 五、路由器技術組播 一、路由器技術NAT NAT:網路地址翻譯,解決IP短缺,路由器內部和外部地址進行轉換。 靜態地址轉換:靜態NAT(一對一) 動
OpenStack設計與實現(五)RESTful API和WSGI
在上一篇部落格中我們提到過,OpenStack每個專案內部的服務程序之間是通過訊息匯流排來通訊的,而在各個專案之間則是通過RESTful API來進行通訊的,在這一篇部落格中,我們就來詳細的討論一下OpenStack各個專案之間的通訊。 一、什麼是RESTfu
使用VMware VSphere WebService SDK進行開發 (五)——根據虛擬機器的名稱獲取對應主機的IP地址
在整個獲取監視資訊的過程中,最難獲取的就是根據虛擬機器的名稱獲得對應主機的IP地址的功能。(個人覺得比較繞,繞了好久我才找到) 首先根據虛擬機器的名稱獲得對應主機(HostSystem)的ManagedObjectReference物件。 RetrieveResult p
資料結構與演算法(五)圖結構
瞭解圖的實現方法,然後從遍歷角度將圖轉化為樹。進而,利用基本資料結構並基於遍歷模式,設計圖演算法的主要方法。最後,從“資料結構決定遍歷次序”出發,概括遍歷演算法。實現選擇和改進資料結構,從而高效實現圖演算法。 1.圖結構含義 圖包含頂點集合V,邊集合E。均為有限集。根據邊有無方向分為無向圖,
百度大腦人臉識別深度驗證與思考(五)之人種識別
環境 win7 32位 VisualStudio2017 python3.6.3 opencv3.3.1 pyQt5.9 baidu-AIP 1.6.9.0 特別宣告 所有圖片均來自網路
Redis之哨兵模式Sentinel配置與啟動(五)
14. quorum rom 修改 rewrite 最大 不可用 log 不可 一、介紹 上一篇我們已經介紹了Redis的主從復制,傳送門:《Redis高可用之主從復制實踐(四)》,想必大家對redis已經有一個概念了,那麽問題來了,如果redis主從復制的mast
資料結構與演算法(五)
malloc函式動態記憶體分配和釋放 #include <stdio.h> #include <malloc.h> int main(void) { int a[5] = {1,2,3,4,5};//靜態記憶體分配 int len; printf("請輸入
Spring Security技術棧開發企業級認證與授權(五)使用Filter、Interceptor和AOP攔截REST服務
一般情況,在訪問RESTful風格的API之前,可以對訪問行為進行攔截,並做一些邏輯處理,本文主要介紹三種攔截方式,分別是:過濾器Filter、攔截器Interceptor以及面向切面的攔截方式AOP。 一、使用過濾器Filter進行攔截 使用過
SVN在 Eclipse 中的配置與使用(五)
具體操作:百度搜索subclipse-site-1.10.x(看自己想安裝哪個版本) --> 解壓縮後在eclipse目錄下找到dropins資料夾,進入dropins資料夾並新建一個資料夾名為svn,將features和plugins資料夾複製到svn目錄下-->重啟下Eclipse即可