Shao Fan

          關(guān)于JAVA與軟件工程
          posts - 31, comments - 71, trackbacks - 0, articles - 4
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          關(guān)于DOM的另一篇

          Posted on 2007-04-01 18:45 shaofan 閱讀(863) 評(píng)論(0)  編輯  收藏 所屬分類: Java其他

          DOM (Document Object Model)是一套語(yǔ)言無(wú)關(guān)的XML解析的接口定義。它定義了在XML解析中需要的類型,方法,以及屬性,比如如何獲得一個(gè)XML標(biāo)簽,如何改變標(biāo)簽的內(nèi)容,如何改變它的屬性,等等。

          DOM只是一個(gè)定義,并不是具體的實(shí)現(xiàn),它的目的就是為了讓大家在各個(gè)平臺(tái)上都能用相同的方式來(lái)處理XML,這樣一來(lái),我只要了解DOM,基本上在各個(gè)平臺(tái)上都可以方便的處理XML,而不用重新學(xué)習(xí)了。比如說(shuō),Java, JavaScript, Python都有DOM的實(shí)現(xiàn),用它們來(lái)處理XML,方式基本上都是一樣的(當(dāng)然也有非DOM的XML解析方式)。在Java下,實(shí)現(xiàn)DOM的類庫(kù)就有很多,比如JDom,Xerces, 用GOOGLE一搜就一大把。現(xiàn)在Java 5.0內(nèi)置的就是Xerces。而JavaScript本身就內(nèi)置了DOM的實(shí)現(xiàn)。Python也默認(rèn)安裝了DOM的庫(kù)。

          正因?yàn)镈OM致力于實(shí)現(xiàn)各個(gè)平臺(tái)上對(duì)XML一致的處理方式,它定義了一堆自己的接口。因此在用DOM的時(shí)候,會(huì)有很多非NATIVE的東東。比如說(shuō),返回節(jié)點(diǎn)的子節(jié)點(diǎn)的方法,childNodes,返回的類型是NodeList。我第一次在Java上用,就以為是返回一個(gè)List,然后用get(n)方法來(lái)取得某元素。而實(shí)際上NodeList是用item(n)的方法來(lái)取得某元素的。這就讓我覺(jué)得很怪。而DOM正是用這種方式來(lái)獲得“語(yǔ)言無(wú)關(guān)”的能力的。

          DOM是用IDL(Interface Definition Language)來(lái)定義的。完整的定義可以在這里找到 http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html。IDL也很容易看懂。定義的1.1節(jié)列出了所有的接口。

          這些接口里,最重要而且常用的是Node,NodeList,Document,Element,Text,Attr這幾個(gè)。DOM把XML文檔看作一棵樹(shù),樹(shù)上的每個(gè)元素都是Node。每個(gè)Node都屬于某個(gè)類型,比如Element,attribute,text等。這些類型就表明這個(gè)節(jié)點(diǎn)在XML文檔里的類型了。

          比如Node里有個(gè)屬性:

          ??readonly?attribute?unsigned? short ??nodeType;

          根據(jù)這個(gè)定義,對(duì)于取得的節(jié)點(diǎn),我們就可以通過(guò)讀取nodeType這個(gè)屬性來(lái)判斷這個(gè)節(jié)點(diǎn)的類型。在Java里,所有的屬性都是用getter來(lái)取得的,因此對(duì)某節(jié)點(diǎn)n,就可以用n.getNodeType()取得它的類型。Node接口里也定義了類型常量:

          ??const?unsigned?short??????ELEMENT_NODE???????????????????=?1;
          ??const?unsigned?short??????ATTRIBUTE_NODE?????????????????=?2;
          ??const?unsigned?short??????TEXT_NODE??????????????????????=?3;
          ??const?unsigned?short??????CDATA_SECTION_NODE?????????????=?4;
          ??const?unsigned?short??????ENTITY_REFERENCE_NODE??????????=?5;
          ??const?unsigned?short??????ENTITY_NODE????????????????????=?6;
          ??const?unsigned?short??????PROCESSING_INSTRUCTION_NODE????=?7;
          ??const?unsigned?short??????COMMENT_NODE???????????????????=?8;
          ??const?unsigned?short??????DOCUMENT_NODE??????????????????=?9;
          ??const?unsigned?short??????DOCUMENT_TYPE_NODE?????????????=?10;
          ??const?unsigned?short??????DOCUMENT_FRAGMENT_NODE?????????=?11;
          ??const?unsigned?short??????NOTATION_NODE??????????????????=?12;

          用這些常量和和n.getNodeType()的結(jié)果比較,就可以知道它是不是某種類型。

          Node接口中也定義了一些方法,比如:

          ?Node?????appendChild(in?Node?newChild)????raises(DOMException);

          表明appendChild方法需要一個(gè)Node類型的參數(shù),返回一個(gè)Node。 具體的說(shuō)明可以點(diǎn)文檔上的鏈接進(jìn)去,也很容易看懂。

          Node接口里定義了操縱節(jié)點(diǎn)的方法,比如增加子節(jié)點(diǎn),返回父節(jié)點(diǎn),插入新節(jié)點(diǎn),返回節(jié)點(diǎn)類型,等等。Document,Element等接口都繼承Node接口,因此在它們上面都可以使用操縱節(jié)點(diǎn)的方法。

          Document:代表整個(gè)XML文檔。所有DOM元素都不能用類似Java里new的方式來(lái)生成,而是要通過(guò)調(diào)用Document里的相應(yīng)方法來(lái)生成。因此它提供了生成諸如Element, Attr, Text的方法。比如createElement, createTextNode, createComment等。它也提供了名為getElementsByTagName的方法,用來(lái)通過(guò)標(biāo)簽名稱來(lái)取得其對(duì)象。比如getElementByTagName("ul")就可以獲得所有ul標(biāo)簽。它也提供一些文檔的屬性,比如xmlEncoding,inputEncoding等。它的一個(gè)屬性,documentElement代表文檔的根節(jié)點(diǎn)。所有對(duì)XML元素的操作,基本上都是從Document開(kāi)始的。

          Element:代表一個(gè)XML標(biāo)簽。它可以有屬性,子標(biāo)簽,等。比如<ul id="booklist"><li>hello</li></ul>。標(biāo)簽ul是一個(gè)Element,它有一個(gè)屬性叫id,屬性的值是booklist。它有一個(gè)子結(jié)點(diǎn)li。li也是一個(gè)標(biāo)簽,它也有個(gè)子節(jié)點(diǎn)hello,是一個(gè)Text類型的節(jié)點(diǎn)。這個(gè)接口提供操縱其標(biāo)簽屬性的方法,比如getAttribute,setAttribute,removeAttribute等。它也提供了和Document中一樣的getElementsByTagName的方法,用來(lái)獲得在這個(gè)節(jié)點(diǎn)下的元素。

          Attr:代表標(biāo)簽中的屬性。比如上面的id。它也是一個(gè)Node。它有名字,值,也可以獲得它的所屬標(biāo)簽。

          Text:代表一段文字,比如上面的hello,它也一個(gè)Node,但比較特殊,它不是直接繼承Node,而是繼承CharacterData接口,后者繼承了Node。但是它不能有子節(jié)點(diǎn)。

          用JavaScript給一個(gè)例子。假設(shè)有一個(gè)HTML文檔:

          < html >< head >< title > Try?DOM </ title ></ head >< body >
          < ul >
          < li > hello </ li >
          < li > world </ li >
          </ ul >
          </ body ></ html >

          下面是增加一個(gè)li的JavaScript方法:

          ulList? = ?document.getElementsByTagName( " ul " );
          ul?????
          = ?ulList.item( 0 );
          txt????
          = ?document.createTextNode( " I?am?new?li " );
          li?????
          = ?document.createElement( " li " );
          li.appendChild(txt);
          ul.appendChild(li);

          用Java來(lái)寫(xiě),是這樣:

          NodeList?ulList? = ?document.getElementsByTagName( " ul " );
          Node??????? ul??????
          = ?ulList.item( 0 );
          Text????????? txt???? ?
          = ?document.createTextNode( " I?am?new?li " );
          Element??? li??? ????
          = ?document.createElement( " li " );
          li.appendChild(txt);
          ul.appendChild(li);

          可以看到處理方式和數(shù)據(jù)類型都是一樣的。如果要了解更多,可以看看DOM的定義,都是IDL。

          主站蜘蛛池模板: 长治县| 广宁县| 岳阳市| 葵青区| 德江县| 广昌县| 台南县| 故城县| 都昌县| 思南县| 汶川县| 玉林市| 临夏市| 洪洞县| 玉田县| 南和县| 盐山县| 刚察县| 郓城县| 昌乐县| 博客| 浪卡子县| 黄大仙区| 云和县| 同心县| 广宁县| 阿拉善左旗| 玉环县| 易门县| 通河县| 英吉沙县| 高邮市| 松潘县| 南涧| 双辽市| 措美县| 二手房| 民和| 安国市| 德惠市| 阿拉善盟|