⼀、介绍及优缺点分析
DOM(Document Object Model)
DOM是⽤与平台和语⾔⽆关的⽅式表⽰XML⽂档的官⽅W3C标准。DOM是以层次结构组织的节点或信息⽚断的集合。这个层次结构允许开发⼈员在树中寻找特定信息。分析该结构通常需要加载整个⽂档和构造层次结构,然后才能做任何⼯作。由于它是基于信息层次的,因⽽DOM被认为是基于树或基于对象的。【优点】
①允许应⽤程序对数据和结构做出更改。
②访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的数据。整个⽂档树在内存中,便于操作;⽀持删除、修改、重新排列等多种功能【缺点】
①通常需要加载整个XML⽂档来构造层次结构,消耗资源⼤。
将整个⽂档调⼊内存(包括⽆⽤的节点),浪费时间和空间;使⽤场合:⼀旦解析了⽂档还需多次访问这些数据;硬件资源充⾜(内存、CPU)SAX(Simple API for XML)
SAX处理的优点⾮常类似于流媒体的优点。分析能够⽴即开始,⽽不是等待所有的数据被处理。⽽且,由于应⽤程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于⼤型⽂档来说是个巨⼤的优点。事实上,应⽤程序甚⾄不必解析整个⽂档;它可以在某个条件得到满⾜时停⽌解析。⼀般来说,SAX还⽐它的替代者DOM快许多。
选择DOM还是选择SAX? 对于需要⾃⼰编写代码来处理XML⽂档的开发⼈员来说, 选择DOM还是SAX解析模型是⼀个⾮常重要的设计决策。 DOM采⽤建⽴树形结构的⽅式访问XML⽂档,⽽SAX采⽤的是事件模型。
DOM解析器把XML⽂档转化为⼀个包含其内容的树,并可以对树进⾏遍历。⽤DOM解析模型的优点是编程容易,开发⼈员只需要调⽤建树的指令,然后利⽤navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然⽽由于使⽤DOM解析器的时候需要处理整个XML⽂档,所以对性能和内存的要求⽐较⾼,尤其是遇到很⼤的XML⽂件的时候。由于它的遍历能⼒,DOM解析器常⽤于XML⽂档需要频繁的改变的服务中。
SAX解析器采⽤了基于事件的模型,它在解析XML⽂档的时候可以触发⼀系列的事件,当发现给定的tag的时候,它可以激活⼀个回调⽅法,告诉该⽅法制定的标签已经找到。SAX对内存的要求通常会⽐较低,因为它让开发⼈员⾃⼰来决定所要处理的tag.特别是当开发⼈员只需要处理⽂档中所包含的部分数据时,SAX这种扩展能⼒得到了更好的体现。但⽤SAX解析器的时候编码⼯作会⽐较困难,⽽且很难同时访问同⼀个⽂档中的多处不同数据。【优势】
①不需要等待所有数据都被处理,分析就能⽴即开始。②只在读取数据时检查数据,不需要保存在内存中。③可以在某个条件得到满⾜时停⽌解析,不必解析整个⽂档。④效率和性能较⾼,能解析⼤于系统内存的⽂档。
不⽤事先调⼊整个⽂档,占⽤资源少;SAX解析器代码⽐DOM解析器代码⼩,适于Applet,下载。【缺点】
①需要应⽤程序⾃⼰负责TAG的处理逻辑(例如维护⽗/⼦关系等),⽂档越复杂程序就越复杂。②单向导航,⽆法定位⽂档层次,很难同时访问同⼀⽂档的不同部分数据,不⽀持XPath。
不是持久的;事件过后,若没保存数据,那么数据就丢了;⽆状态性;从事件中只能得到⽂本,但不知该⽂本属于哪个元素;使⽤场合:Applet;只需XML⽂档的少量内容,很少回头访问;机器内存少。JDOM(Java-based Document Object Model)
JDOM的⽬的是成为Java特定⽂档模型,它简化与XML的交互并且⽐使⽤DOM实现更快。由于是第⼀个Java特定模
型,JDOM⼀直得到⼤⼒推⼴和促进。正在考虑通过“Java规范请求JSR-102”将它最终⽤作“Java标准扩展”。从2000年初就已经开始了JDOM开发。
JDOM与DOM主要有两⽅⾯不同。⾸先,JDOM仅使⽤具体类⽽不使⽤接⼝。这在某些⽅⾯简化了API,但是也限制了灵活性。第⼆,API⼤量使⽤了Collections类,简化了那些已经熟悉这些类的Java开发者的使⽤。
JDOM⽂档声明其⽬的是“使⽤20%(或更少)的精⼒解决80%(或更多)Java/XML问题”(根据学习曲线假定为20%)。
JDOM对于⼤多数Java/XML应⽤程序来说当然是有⽤的,并且⼤多数开发者发现API⽐DOM容易理解得多。JDOM还包括对程序⾏为的相当⼴泛检查以防⽌⽤户做任何在XML中⽆意义的事。然⽽,它仍需要您充分理解XML以便做⼀些超出基本的⼯作(或者甚⾄理解某些情况下的错误)。这也许是⽐学习DOM或JDOM接⼝都更有意义的⼯作。
JDOM⾃⾝不包含解析器。它通常使⽤SAX2解析器来解析和验证输⼊XML⽂档(尽管它还可以将以前构造的DOM表⽰作为输⼊)。它包含⼀些转换器以将JDOM表⽰输出成SAX2事件流、DOM模型或XML⽂本⽂档。JDOM是在Apache许可证变体下发布的开放源码。【优点】
①使⽤具体类⽽不是接⼝,简化了DOM的API。②⼤量使⽤了Java集合类,⽅便了Java开发⼈员。【缺点】
①没有较好的灵活性。②性能较差。
DOM4J(Document Object Model for Java)
虽然DOM4J代表了完全独⽴的开发结果,但最初,它是JDOM的⼀种智能分⽀。它合并了许多超出基本XML⽂档表⽰的功能,包括集成的XPath⽀持、XML Schema⽀持以及⽤于⼤⽂档或流化⽂档的基于事件的处理。它还提供了构建⽂档表⽰的选项,它通过DOM4J API和标准DOM接⼝具有并⾏访问功能。从2000下半年开始,它就⼀直处于开发之中。
为⽀持所有这些功能,DOM4J使⽤接⼝和抽象基本类⽅法。DOM4J⼤量使⽤了API中的Collections类,但是在许多情况下,它还提供⼀些替代⽅法以允许更好的性能或更直接的编码⽅法。直接好处是,虽然DOM4J付出了更复杂的API的代价,但是它提供了⽐JDOM⼤得多的灵活性。
在添加灵活性、XPath集成和对⼤⽂档处理的⽬标时,DOM4J的⽬标与JDOM是⼀样的:针对Java开发者的易⽤性和直观操作。它还致⼒于成为⽐JDOM更完整的解决⽅案,实现在本质上处理所有Java/XML问题的⽬标。在完成该⽬标时,它⽐JDOM更少强调防⽌不正确的应⽤程序⾏为。
DOM4J是⼀个⾮常⾮常优秀的Java XML API,具有性能优异、功能强⼤和极端易⽤使⽤的特点,同时它也是⼀个开放源代码的软件。如今你可以看到越来越多的Java软件都在使⽤DOM4J来读写XML,特别值得⼀提的是连Sun的JAXM也在⽤DOM4J.【优点】
①⼤量使⽤了Java集合类,⽅便Java开发⼈员,同时提供⼀些提⾼性能的替代⽅法。②⽀持XPath。③有很好的性能。【缺点】
①⼤量使⽤了接⼝,API较为复杂。总结:
如果XML⽂档较⼤且不考虑移植性问题建议采⽤DOM4J;如果XML⽂档较⼩则建议采⽤JDOM;
如果需要及时处理⽽不需要保存数据则考虑SAX。
适合⾃⼰的才是最好的,如果时间允许,建议⼤家讲这四种⽅法都尝试⼀遍然后选择⼀种适合⾃⼰的即可。下⾯解析实现过程:
1、⾸先新建个test.xml⽂件
2、创建xmlDocument.java
public interface XmlDocument { /**
* 解析XML⽂档 * @param fileName * ⽂件全路径名称 */
public void parserXml(String fileName);}
3、列出四种⽅式的实现dom4j的实现
//dom4j的实现
public class Dom4jTest implements XmlDocument { public void parserXml(String fileName) { File inputXml = new File(fileName);
SAXReader saxReader = new SAXReader();
try {
Document document = saxReader.read(inputXml); Element users = document.getRootElement();
for (Iterator i = users.elementIterator(); i.hasNext();) { Element user = (Element) i.next();
for (Iterator j = user.elementIterator(); j.hasNext();) { Element node = (Element) j.next();
System.out.println(node.getName() + \":\" + node.getText()); }
System.out.println(); }
} catch (DocumentException e) {
System.out.println(e.getMessage()); } }
public static void main(String[] args) { Dom4jTest domj4= new Dom4jTest(); //获取⽂件路径
String path = Dom4jTest.class.getClassLoader().getResource(\"test.xml\").getPath(); System.out.println(path); domj4.parserXml(path); }
dom的实现
//dom的实现
public class DomTest implements XmlDocument {
private Document document;
public void parserXml(String fileName) { try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document document = db.parse(fileName); NodeList users = document.getChildNodes();
for (int i = 0; i < users.getLength(); i++) { Node user = users.item(i);
NodeList userInfo = user.getChildNodes(); for (int j = 0; j < userInfo.getLength(); j++) { Node node = userInfo.item(j);
NodeList userMeta = node.getChildNodes();
for (int k = 0; k < userMeta.getLength(); k++) { if(userMeta.item(k).getNodeName() != \"#text\")
System.out.println(userMeta.item(k).getNodeName() + \":\" + userMeta.item(k).getTextContent()); }
System.out.println(); } }
} catch (FileNotFoundException e) { e.printStackTrace();
} catch (ParserConfigurationException e) { e.printStackTrace();
} catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
public static void main(String[] args) { DomTest domj4= new DomTest(); //获取⽂件路径
String path = Dom4jTest.class.getClassLoader().getResource(\"test.xml\").getPath(); System.out.println(path); domj4.parserXml(path); }}}
sax的实现
//sax的实现
public class SaxTest implements XmlDocument {
public void parserXml(String fileName) {
SAXParserFactory saxfac = SAXParserFactory.newInstance(); try {
SAXParser saxparser = saxfac.newSAXParser(); InputStream is = new FileInputStream(fileName); saxparser.parse(is, new MySAXHandler()); } catch (ParserConfigurationException e) { e.printStackTrace();
} catch (SAXException e) { e.printStackTrace();
} catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
public static void main(String[] args) { SaxTest saxTest = new SaxTest();
String path = Dom4jTest.class.getClassLoader().getResource(\"test.xml\").getPath(); saxTest.parserXml(path); }}
class MySAXHandler extends DefaultHandler { boolean hasAttribute = false;
Attributes attributes = null;
public void startDocument() throws SAXException { // System.out.println(\"⽂档开始打印了\"); }
public void endDocument() throws SAXException { // System.out.println(\"⽂档打印结束了\"); }
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equals(\"users\")) { return; }
if (qName.equals(\"user\")) { return; }
if (attributes.getLength() > 0) { this.attributes = attributes; this.hasAttribute = true; } }
public void endElement(String uri, String localName, String qName) throws SAXException {
if (hasAttribute && (attributes != null)) {
for (int i = 0; i < attributes.getLength(); i++) {
System.out.print(attributes.getQName(0) + \":\" + attributes.getValue(0)); } } }
public void characters(char[] ch, int start, int length) throws SAXException { System.out.print(new String(ch, start, length)); }}
jdom的实现
//jdom的实现
public class JdomTest implements XmlDocument {
public void parserXml(String fileName) { SAXBuilder builder = new SAXBuilder(); try {
Document document = builder.build(fileName); Element users = document.getRootElement(); List userList = users.getChildren(\"user\"); for (int i = 0; i < userList.size(); i++) {
Element user = (Element) userList.get(i); List userInfo = user.getChildren(); for (int j = 0; j < userInfo.size(); j++) {
System.out.println(((Element) userInfo.get(j)).getName() + \":\" + ((Element) userInfo.get(j)).getValue()); }
System.out.println(); }
} catch (JDOMException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
}
public static void main(String[] args) { JdomTest jdomTest = new JdomTest();
String path = Dom4jTest.class.getClassLoader().getResource(\"test.xml\").getPath(); jdomTest.parserXml(path); }}
到这⾥,这四种实现⽅式都可以⽤了,个⼈的见解是:推荐使⽤dom4j的⽅式。以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
因篇幅问题不能全部显示,请点此查看更多更全内容