虽然sun公司的xml解析性能不是最好的,但方便,不需要导入第三方包。
<?xml version="1.0" standalone="yes"?> <Root> <VID>2012/2/20 15:33:36</VID> <Mac>000B6CCCAE2C</Mac> <ServerIP>191.255.1.102</ServerIP> <ServerPort>3130</ServerPort> <PassWord>111111</PassWord> <System>Android2.3</System> </Root>
Dom解析中有三个重要的类,分别是Document、Element、Node
Docuement代表着整个XML文件。
Element代表一个元素,比如上面的<VID>2012/2/20 15:33:36</VID>就是一个元素。<Root>到</Root>也是一个元素。
Node 代表着一个节点,这里所谓节点就是指用<>包起来的对象,比如<Root>就是一个节点。需要注意,Node是个超级接口,Docuement与Element都是其子类。
弄明白上面三个类所代表的东西后,解析就容易了。
创建Dom解析器,并解析XML文件得到Document对象。被解析的对象可以是流、文件或者文件路径
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document d = db.parse(PATH);
下面介绍一些解析可能要用到的方法
Document
NodeList getElementsByTagName(String tagname) 根据标签名得到有这个标签的所有节点。(首节点下的子节点)
Element getDocumentElement() 得到第一条元素,比如上面的XML就会得到代表<Root>的元素对象
Element
String getTagName() 得到标签名,就是得到<>里面包含的名字,与继承自Node的getNodeName结果一样。
NodeList getElementsByTagName(String name) 根据标签名得到这个元素的所有子元素具有这个标签名的节点。(元素节点下的子节点)
String getAttribute(String name) 通过属性名得到属性值
NodeList
int getLength() 节点数
Node item(int index) 返回指定位置的节点
Node
Node getParentNode() 得到父节点
Node getFirstChild() 得到此节点的第一个子节点
Node getLastChild() 得到此接节点的最后一个子节点
String getNodeName() 得到节点名
Document getOwnerDocument() 得到与节点相关的整个文档对象。
Node getNextSibling() 得到下一个节点。(注意:得到的必然是结束节点,得到的节点都是同一深度的节点,不会为子节点)
Node getPreviousSibling() 得到上一个节点。与上方法一样可能为null。(结束节点使用 getNodeName方法得到的是节点类型,不会是节点标签)
NamedNodeMap getAttributes() //......
String getTextContent() 得到此节点中间的文本值,就是我们需要的数据了。
要想掌握Dom解析,对照着上面的方法写吧!
Dom生成XML文件
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document d =db.newDocument();如果不是生成新的XML文件,而是改动原有的XML文件,上面得到Document对象的方法改为解析时的方法。
生成XML或者改动XML文件需要用到的方法
Document(文档)
Element createElement(String tagName) 创建一个新的元素
String getXmlEncoding() 得到编码类型
boolean getXmlStandalone() 是否为独立文档
String getXmlVersion() 得到版本声明
void setXmlStandalone(boolean xmlStandalone) (false就会出现standalone="no",true不出现)
void setXmlVersion(String xmlVersion) 就一个版本,默认也是1.0
Element(元素)
boolean hasAttributes() 是否有属性
void setAttribute(String name, String value) 给元素增加一个属性
void removeAttribute(String name) 通过名称移除一条属性。如果为只读抛DOMException异常
Node(节点)
Node appendChild(Node newChild) 把新节点挂到此节点上成为此节点的子节点。
void setTextContent(String textContent) 设置此节点后的文本内容。
Node replaceChild(Node newChild, Node oldChild) 将子节点中的oldChild替换为newChild节点。
Node removeChild(Node oldChild) 移除此节点的oldChild子节点。
boolean hasChildNodes() 是否有子节点
上面所说的节点都是指的标签节点,标签节点其实还有一个子节点,那就是Text节点,不过对XML来说好像用不上。
Text
String getWholeText() 得到整个文本内容,结果一般等同于node的 getTextContent() ,返回 Text
节点(逻辑上与此节点相邻的节点)的以文档顺序串接的所有文本
Text replaceWholeText(String content) 将当前节点和所有逻辑上相邻的文本节点的文本替换为指定的文本(没测)
Text splitText(int offset) 在指定的 offset
处将此节点拆分为两个节点,并将二者作为兄弟节点保持在树中(没测)
当写好(修改)好需要的XML文件后需要将其作为文件存到存储设备上
public static void saveMyDocument(Node node) throws TransformerException{ TransformerFactory tf = TransformerFactory.newInstance(); Transformer t = tf.newTransformer(); t.setOutputProperty(OutputKeys.INDENT, "yes"); Result r = new StreamResult(new File("E:/aaa.xml")); t.transform(new DOMSource(node), r); }
Transformervoid transform(Source xmlSource, Result outputTarget) 把源Source接口的实现类对象转为Result接口的实现类对象
void setOutputProperty(String name, String value) 设置转化时的参数,参数的键参照OutputKeys类的字段
OutputKeys
String ENCODING 编码
String INDENT 是否为漂亮格式,默认为紧凑格式,漂亮格式指的是上面的那种XML格式。可选值为 “yes”与“no”
Source 接口一般用DOMSource实现,构造方法DOMSource(Node n)
Result 接口一般用StreamResult实现,构造方法有StreamResult(File f) 、StreamResult(OutputStream outputStream) 、StreamResult(Writer writer)
生成最上面那个XML文件的方法如下:
public void createXml() throws ParserConfigurationException, TransformerException{ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document d =db.newDocument(); d.setXmlVersion("1.0"); d.setXmlStandalone(true); Element root = d.createElement("Root"); d.appendChild(root); Element e = d.createElement("VID"); e.setTextContent("2012/2/20 15:33:36"); root.appendChild(e); e = d.createElement("Mac"); e.setTextContent("000B6CCCAE2C"); root.appendChild(e); e = d.createElement("ServerIP"); e.setTextContent("191.255.1.102"); root.appendChild(e); e = d.createElement("ServerPort"); e.setTextContent("3130"); root.appendChild(e); e = d.createElement("PassWord"); e.setTextContent("111111"); root.appendChild(e); e = d.createElement("System"); e.setTextContent("Android2.3"); root.appendChild(e); DoXml.saveMyDocument(d); }
public static void saveMyDocument(Node node) throws TransformerException{ TransformerFactory tf = TransformerFactory.newInstance(); Transformer t = tf.newTransformer(); t.setOutputProperty(OutputKeys.INDENT, "yes"); Result r = new StreamResult(new File("E:/aaa.xml")); t.transform(new DOMSource(node), r); }
不足的地方:
1.获取属性时,必须要知道属性名才能得到属性值,而不能直接得到所有属性名与值。
2.获取子节点时只有得到此节点下的节点(不包括子节点的子节点)的方法getChildNodes,而没有得到此节点的所有子节点的方法(包含子节点的子节点)。