XML

主要介紹解析XML的兩種方式

DOM4J解析:面向?qū)ο笊矶捎谑且淮涡宰x取整個文檔到內(nèi)存中玄括,讀取大文件的時候可能會造成內(nèi)存占用過多鸦泳。
SAX解析:基于事件银锻,一次讀取一部分,操作上比DOM4J繁瑣一點做鹰,不會造成內(nèi)存占用問題击纬。

DOM 解析 SAX 解析
原理 一次性加載,內(nèi)存占用比較大 加載一點钾麸,讀取一點更振,內(nèi)存占用小
讀取順序 可以任意讀取,可以往回讀 只能從上往下依次讀取饭尝,不能往回讀
操作方式 可查詢肯腕,也可修改 只能查詢
編碼方式 面向?qū)ο?/td> 基于事件

大綱

  1. DOM4J 解析
    1. 導包
    2. 核心類和方法
    3. 讀取XML
    4. 寫出XML
    5. XPath
  2. SAX 解析 jdk集成
    1. 核心類
    2. 讀取XML文件加載對象到容器 DEMO

#DOM4J 解析

dom4j是一個Java的XML API,是jdom的升級品钥平,用來讀寫XML文件的实撒。dom4j是一個十分優(yōu)秀的JavaXML API,具有性能優(yōu)異涉瘾、功能強大和極其易使用的特點知态,它的性能超過sun公司官方的dom技術,同時它也是一個開放源代碼的工具立叛。


##導包 下載JAR包
  • dom4j-1.6.1.jar

##核心類和方法

SAXReader:負責XML文件的加載
XMLWriter:負責XML文件的輸出
DocumentHelper:用來生成生成 XML 文檔的工廠類
Element:元素節(jié)點

三個重要概念:標簽负敏、屬性、文本

  • 標簽 Element
Method Method Description
getRootElement() 得到文檔根元素
addElement("name") 添加子標簽
element("name") 尋找指定標簽名的子元素
elements("names") 尋找指定標簽名的子元素(全部)
elements() 尋找全部子元素
  • 屬性 Atrribute
Method Method Description
atrributeValue("name") 得到指定屬性的值
addAtribute("name", "value") 添加屬性(以存在則修改)
atrribute("name") 得到屬性對象
atrributes() 全部屬性對象列表
getName() 得到屬性名
getValue() 得到屬性值
  • 文本
Method Method Description
getText() 得到文本信息
setText() 修改文本信息
elementText("name") 得到子標簽的文本信息
  • 其他

DocumentHelper.createDocument():創(chuàng)建新文檔
detach():標簽/屬性 自殺
getParent().remove(標簽/屬性):調(diào)用父類的刪除方法來刪除標簽/屬性


##讀取XML
/**
 * loading XML File Resource
 * @param path XML Resource File Path
 * @return XML Document Object
 */
public static Document reader(String path) {
    Document document = null;
    try {
        return new SAXReader().read(XMLTools.class.getClassLoader().getResourceAsStream(path));
    } catch (DocumentException e) {
        e.printStackTrace();
    }
        return document;
}

Document read(File file)
Document read(URL url)
Document read(String systemId)
Document read(InputStream in)
Document read(Reader reader)

##寫出XML
/**
 * Writer XML File Resource
 * @param document XML Document Object
 * @param path XML Resource File Path
 * @return result
 */
public static boolean writer(Document document, String path) {
    boolean flag = true;
    try {
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(
            new FileWriter(XMLTools.class.getClassLoader().getResource(path).getPath()),
            format
        );

        writer.write(document);
        writer.close();
    } catch (Exception e) {
        flag = false;
        e.printStackTrace();
    }
    return flag;
}

##XPath XPath語法
  • 導包:jaxen-1.1-beta-6.jar
// 搜索多個節(jié)點
List<Node> nodes = document.selectNodes(XPath表達式);
// 搜索單個節(jié)點
Node node = document.selectSingleNode(XPath表達式);

#SAX 解析 jdk集成

SAX秘蛇,全稱Simple API for XML其做,既是一種接口,也是一種軟件包赁还。它是一種XML解析的替代方法庶柿。SAX不同于DOM解析,它逐行掃描文檔秽浇,一邊掃描一邊解析浮庐。由于應用程序只是在讀取數(shù)據(jù)時檢查數(shù)據(jù),因此不需要將數(shù)據(jù)存儲在內(nèi)存中,這對于大型文檔的解析是個巨大優(yōu)勢审残。


##核心類

SAXParser:負責解析XML
DefaultHandler:負責監(jiān)聽加載XML觸發(fā)的事件

  • DefaultHandler 自定義一個類繼承DefaultHandler類
    • startDocument():文檔開始
    • endDocument():文檔結束
    • startElement():元素開始
    • endElement():元素結束
    • characters():文本 當前元素的 text 加載完
##讀取XML配置加載對象到容器

下面是一個讀取XML文件梭域,通過反射技術生成對象并存放到容器的Demo

LoadObjectHandler.java

/**
 * 讀取XML文件加載對象到容器
 */
public class LoadObjectHandler extends DefaultHandler {
    public static final String BEAN_NODE = "bean";
    public static final String BEAN_NAME = "name";
    public static final String BEAN_CLASS = "class";

    // Object Container
    private Map<String, Object> container = new HashMap<>();

    /**
     * 元素開始
     *
     * @param uri
     * @param localName
     * @param qName      標簽名
     * @param attributes 屬性列表
     * @throws SAXException
     */
    @Override
    public void startElement(String uri, String localName, String qName,
                             Attributes attributes) throws SAXException {

        if (qName != null && qName.equals(BEAN_NODE)) {
            if (attributes != null) {
                for (int i = 0; i < attributes.getLength(); i++) {
                    String name = attributes.getValue(BEAN_NAME);
                    String clazz = attributes.getValue(BEAN_CLASS);

                    try {
                        Class<?> mClass = getClass().forName(clazz);
                        Object obj = mClass.newInstance();
                        container.put(name, obj);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 從容器返回對象
     *
     * @param name Object key
     * @return Object
     */
    public Object getObject(String name) {
        return container.get(name);
    }
}

test.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean name="User" class="tools.xml.test1.User"/>
</beans>

App.java

String path = "../resource/test.xml";

// 從工廠得到解析器
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
// 創(chuàng)建自定義監(jiān)聽器對象
LoadObjectHandler handler = new LoadObjectHandler();
// 解析XML文件
parser.parse(new File(XMLTools.class.getResource(path).getPath()), handler);
System.out.println(handler.getObject("User"));

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市搅轿,隨后出現(xiàn)的幾起案子病涨,更是在濱河造成了極大的恐慌,老刑警劉巖璧坟,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件既穆,死亡現(xiàn)場離奇詭異,居然都是意外死亡雀鹃,警方通過查閱死者的電腦和手機幻工,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來黎茎,“玉大人囊颅,你說我怎么就攤上這事「嫡埃” “怎么了踢代?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長嗅骄。 經(jīng)常有香客問我胳挎,道長,這世上最難降的妖魔是什么溺森? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任慕爬,我火速辦了婚禮,結果婚禮上儿惫,老公的妹妹穿的比我還像新娘澡罚。我一直安慰自己伸但,他們只是感情好肾请,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著更胖,像睡著了一般铛铁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上却妨,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天饵逐,我揣著相機與錄音,去河邊找鬼彪标。 笑死倍权,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的捞烟。 我是一名探鬼主播薄声,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼当船,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了默辨?” 一聲冷哼從身側(cè)響起德频,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎缩幸,沒想到半個月后壹置,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡表谊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年钞护,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片铃肯。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡患亿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出押逼,到底是詐尸還是另有隱情步藕,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布挑格,位于F島的核電站咙冗,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏漂彤。R本人自食惡果不足惜雾消,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望挫望。 院中可真熱鬧立润,春花似錦、人聲如沸媳板。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛉幸。三九已至破讨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間奕纫,已是汗流浹背提陶。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留匹层,地道東北人隙笆。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親撑柔。 傳聞我的和親對象是個殘疾皇子煤率,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355