首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > XML SOAP >

(2) 解析XML文档(parse xml)

2012-09-04 
(二) 解析XML文档(parse xml)Java库提供了两种XML解析器(1)文档对象模型(Document Object Model, DOM)解析

(二) 解析XML文档(parse xml)

Java库提供了两种XML解析器
(1)文档对象模型(Document Object Model, DOM)解析器,树形解析器(tree parser),将读入的XML转换成树形结构。
(2)用于XML的简单API(Simple API for XML,SAX)解析器,流机制解析器(streaming parser),在读入XML文档时生成相应的事件。

1.DOM解析器
当处理大文档时,树结构将会消耗大量内存,或只针对于某些元素时,应选用流机制解析器(SAX)。
(1)读入一个XML文档,需要一个DocumentBuilder对象,可以从DocumentBuilderFactory中得到这个对象。

    javax.xml.parsers.DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();    javax.xml.parsers.DocumentBuilder builder = factory.newDocumentBuilder();

?

(2)读入文档 org.w3c.dom.Document

?

org.w3c.dom.Document doc = builder.parse(file);

?

? ? 或者用URL

org.w3c.dom.Document doc = builder.parse(url);
?

?? 或使用一个任意的输入流

org.w3c.dom.Document doc = builder.parse(inputStream);
?

注意:如果使用输入流,那么对于通过相对于文档的位置关系来引用的文件,解析器将无法定位,比如在同一个目录中的DTD。但是可以通过安装一个 实体分解器(entity resolver) 来解决这个问题。

(3)Document对象是XML文档的树型结构在内存中的表现,它由实现Node接口及其多个子接口的类的对象构成。可以通过调用getDocumentElement方法来分析文档的内容,它将返回root element(根元素)。

org.w3c.dom.Element root = doc.getDocumentElement();
?

(4)要得到该元素的下一个节点(子元素、文本、注释或其他节点),使用getChildNodes方法。这个方法返回一个类型为NodeList的集合。NodeList集合
NodeList在标准Java集合类创建之前就建立了,与标准Java集合类访问协议不同。item方法得到指定索引号的项,getLength方法返回项的总数。
e.g.枚举所有子元素

    org.w3c.dom.NodeList childNodes = roog.getChildNodes();    for(int i=0;i<childNodes.getLength();i++){        org.w3c.dom.Node childNode = childNodes.item();    }
?

注意:子元素会比期望值高

?

    <font>        <name>Helvetica</name>        <size>36</size>    </font>

?

font会有5个子节点,而不是期望中的2个。<font>和<name>之间的空格,name元素,</name>和<size>之间的空白字符,size元素,</size>和</font>之间的空白字符。
如果只希望得到子元素,需要忽略空白字符

?

    for(int i=0;i<childNodes.getLength();i++){        Node child = childNodes.item(i);        if(child instanceof Element){            Element childElement = (Element)child;        }    }
?


如果有DTD,解析器就可以知道哪些元素没有文本节点的子元素,而且会帮助禁止掉空白字符。
(5)分析子元素所包含的文本字符串org.w3c.dom.Text,比如上例中的name和size。这些文本字符串本身都包含在Text类型的子节点中。因为Text类型是唯一的子元素,可以用getFirstChild方法,而不用遍历一个NodeList。然后用getData方法检索存储在Text节点中的字符串。

?

    NodeList childNodes = root.getChildNodes();    for(int i=0;i<childNodes.getLength();i++){        Node child = childNodes.item(i);        if(child instanceof Element){            Element childElement = (Element)child;            Text textNode = (Text)childElement.getFirstChild();            String text = textNode.getData().trim();            if("name".equals(childElement.getTagName())){                name = text;            }else if("size".equals(childElement.getTagName())){                size = text;            }                   }    }

?

对getData方法的返回值调用trim方法。因为起始和结束标签可能不在同一行上,导致空白字符

也可以用getLastChild方法得到最后一项子元素

?

    Document doc = builder.parse(xml);    Element root = doc.getDocumentElement();       for(Node childNode = root.getFirstChild();childNode !=null;childNode  = childNode.getNextSibling()){        if(childNode instanceof Element){            Text textNode = (Text)childNode.getLastChild();            String text = textNode.getData();        }    }
?


(6)枚举节点的属性,通过调用Node的getAttributes方法,如果节点是Element返回NamedNodeMap,否则返回null。

?

    if(childNode instanceof Element){        NamedNodeMap attributes = childNode.getAttributes();        for(int i=0;i<attributes.getLength();i++){            Node attribute = attributes.item(i);            String name = attribute.getNodeName();            String value = attribute.getNodeValue();            System.out.println();        }    }

?

或者根据已知的属性名,得到通过Element的getAttribute(String name) 来获得属性,如果没有指定值或默认值,则返回空字符串。

?

    if(childNode instanceof Element){        Element childElement = (Element)childNode;        String value = childElement.getAttribute("unit");        System.out.println(value);    }
?

?

热点排行