Android中操作XML——DOM篇
| 1 2 3 4 5 | import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; | 
在Android开发中我们可以通过DOM、Sax、Pull这几种方法来操作XML。其中DOM是大家都比较熟悉的方法,如果使用过其他开发工具的人肯定也都用过相应的DOM方法来解析过XML。
要在Android中操作XML必须先要定义一个DocumentBuilderFactory实例,此实例用于设置一些解析时相关的属性,比如是否解析comment类型的节点、是否忽略xml文件内容中的空白字符等,另外比较重要的一点是,它的newDocumentBuilder函数是用来创建一个DocumentBuilder对象的。该类的实例由它本身的一个静态函数newInstance来创建。
| 1 | DocumentBuilderFactory docBF = DocumentBuilderFactory.newInstance(); | 
创建了DocumentBuilderFactory并设置相关的属性(如果需要)后,我们就可以创建一个DocumentBuilder对象了。DocumentBuilder对象是用来从各种源(输入流、文件、URL、InputSource)中载入XML文档的类,并不负责操作XML中的各节点和属性。
| 1 | DocumentBuilder docB = docBF.newDocumentBuilder(); | 
有了DocumentBuilder我们就可以从不同的源中载入xml文档了,我们需要使用Parse函数。如:
| 1 | Document doc = docB.Parse("/mnt/sdcard/doc.xml"); | 
如果是要从一个xml字符串中加载xml则可以使用如下方法
| 1 2 3 | String xmlStr = ""; InputStream inputStream = new ByteArrayInputStream(xmlStr.getBytes()); Document doc = docB.parse(inputStream); | 
也许你是要创建一个全新的XML文档并在此基础上添加数据,那么你可以使用如下代码:
| 1 | Document doc = docB.NewDocument(); | 
下面代码介绍如何读取XML中的内容,XML文件内容如下:
| 1 2 3 4 5 6 7 8 9 10 11 | <?xml version="1.0" encoding="utf-8"?> <UserList>   <User Name="Liu" ID="1">     <Website><![CDATA[http://svn1.bcoder.com]]></Website>     <Intro>I come from hebei.</Intro>   </User>   <User Name="Zhang" ID="2">     <Website><![CDATA[http://www.desktoptool.net]]></Website>     <Intro>I come from Shandong.</Intro>   </User> </UserList> | 
下面的代码读取XML内容并显示到一个EditText中
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 	DocumentBuilderFactory docBF = DocumentBuilderFactory.newInstance(); 	DocumentBuilder docB; 	try { 		docB = docBF.newDocumentBuilder();                 String resStr = "你的XML字符串"; 		InputStream inputStream = new ByteArrayInputStream(resStr.getBytes()); 		Document doc = docB.parse(inputStream); 		Element rootNode = doc.getDocumentElement(); 		NodeList uNodeList = rootNode.getChildNodes(); 		for (int i=0; i<uNodeList.getLength()- 1; i++){ 			if (uNodeList.item(i).getNodeName().equals("User")) { 				etXmlValues.append("ID:" + uNodeList.item(i).getAttributes().getNamedItem("ID").getNodeValue()); 				etXmlValues.append("rn"); 				etXmlValues.append("Name:" + uNodeList.item(i).getAttributes().getNamedItem("Name").getNodeValue()); 				etXmlValues.append("rn"); 				for(Node cNode = uNodeList.item(i).getFirstChild(); cNode != null; cNode = cNode.getNextSibling()){ 					if (cNode.getNodeType() == Node.ELEMENT_NODE){ 						if (cNode.getNodeName().equals("Website")) { 							etXmlValues.append("WEB:" + cNode.getTextContent()); 							etXmlValues.append("rn"); 						} else if (cNode.getNodeName().equals("Intro")) { 							etXmlValues.append("INTRO:t" + cNode.getTextContent()); 							etXmlValues.append("rn"); 						} 					} 				} 				etXmlValues.append("rn"); 			} 		} 	} catch (ParserConfigurationException e) { 		// TODO Auto-generated catch block 		e.printStackTrace(); 	} catch (SAXException e) { 		// TODO Auto-generated catch block 		e.printStackTrace(); 	} catch (IOException e) { 		// TODO Auto-generated catch block 		e.printStackTrace(); 	} | 
其中的几个常用的函数为:
getChildNodes(): 获取某节点下的所有子节点
getNodeName(): 获取节点的名称
getAttributes().getNamedItem(“ID”).getNodeValue(): 获取节点中属性名为ID的值
getFirstChild(): 获取某节点下的第一个子节点
getNextSibling(): 获取某个节点的紧邻的下一个节点
getNodeType(): 获取节点的类型,通过需要判断节点类型为Node.ELEMENT_NODE才继续解析,关于xml的节点类型请参考此文章
getTextContent(): 获取某节点中所包括的文本内容
向XML文件中添加数据的代码
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | 	public void SaveNewValues(View V) throws ParserConfigurationException, NotFoundException, SAXException, IOException, TransformerException{ 		EditText etnId = (EditText)findViewById(R.id.etAddId); 		EditText etnName = (EditText)findViewById(R.id.etAddName); 		EditText etnWebsite = (EditText)findViewById(R.id.etAddWebsite); 		EditText etnIntro = (EditText)findViewById(R.id.etAddIntro); 		String nId = etnId.getText().toString(); 		String nName = etnName.getText().toString(); 		String nWebsite = etnWebsite.getText().toString(); 		String nIntro = etnIntro.getText().toString(); 		DocumentBuilderFactory docBF = DocumentBuilderFactory.newInstance(); 		DocumentBuilder docB = docBF.newDocumentBuilder(); 		//Document doc = docB.newDocument(); 		Document doc = docB.parse(getResources().openRawResource(R.raw.sample_xml)); 		Element rootNode = doc.getDocumentElement(); 		Element nUNode = doc.createElement("User"); 		rootNode.appendChild(nUNode); 		nUNode.setAttribute("ID", nId); 		nUNode.setAttribute("Name", nName); 		Node nodeWeb = doc.createElement("Website"); 		nodeWeb.appendChild(doc.createCDATASection(nWebsite)); 		nUNode.appendChild(nodeWeb); 		Node nodeIntro = doc.createElement("Intro"); 		nodeIntro.appendChild(doc.createTextNode(nIntro)); 		nUNode.appendChild(nodeIntro); 		TransformerFactory factory = TransformerFactory.newInstance(); 		Transformer transformer = factory.newTransformer(); 		Result result = new StreamResult(new File("/mnt/sdcard/doc.xml")); 		Source source = new DOMSource(doc); 		transformer.transform(source, result); 	} | 
其他问题:
1. 使用该方法解析xml时出现Unexpected token (position:TEXT @1:2 in java.io.StringReader@40e31480) 的错误,解决办法:因为要解析的xml文件使用的是UTF8带BOM的格式,所以在解析的时候出现错误,将xml的编码格式改为UTF8无BOM格式后问题解决。

 
                 微信扫一扫,打赏作者吧~
微信扫一扫,打赏作者吧~