DOM解析XML解决空格问题
2017-12-30 22:22
447 查看
DOM解析XML问题
BUG:之所以称之为bug,是因为我认为DOM应该忽略非元素包括内的空白,而把空白也当成一个子节点。解决办法是判断子节点是否为元素节点,但是这会让代码感觉非常难受,所以应该在XML的可读性和程序的简洁性中做出选择。
成功解析XML两种方案:
删除所有空格
增加判断是否为元素节点
XML
<?xml version="1.0" encoding="UTF-8"?> <users> <!--a classic customer --> <customer> <id>1</id> <name>oneslide</name> <password>123456789</password> <contact>oneslideicywater@qq.com</contact> </customer> </users>
[NOTE]
以下的java文件普遍出现在解析XML的过程中,因为XML中存在的空格问题,所以需要假如一些判断条件,就是
nodelist.item(j).getNodeType()==Node.ELEMENT_NODE,这条语句判断是否为一个元素(不是空格)!
Java
import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.List; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * Servlet implementation class login */ @WebServlet("/login") public class login extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public login() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name=request.getParameter("username"); String password=request.getParameter("password"); String contact=request.getParameter("contact"); System.out.println("User Infomation Collection completed"); System.out.println("name="+name+"\n password="+password+"\ncontact="+contact); String choice1=request.getParameter("choice"); int choice=Integer.parseInt(choice1); System.out.println("choice="+choice); //judge you want to sign up or login //XML的文件绝对路径 String Userurl="D:\\workbunch\\bookengine4\\WebContent\\data\\user.xml"; try { DocumentBuilderFactory builder=DocumentBuilderFactory.newInstance(); DocumentBuilder db; try { db = builder.newDocumentBuilder(); Document docu=db.parse(Userurl); NodeList clist=docu.getElementsByTagName("customer"); for(int i=0;i<clist.getLength();i++){ Node node=clist.item(i); NodeList nodelist=node.getChildNodes(); for(int j=0;j<nodelist.getLength();j++){ if(nodelist.item(j).getNodeType()==Node.ELEMENT_NODE){ //如果有空格,最好加上面的选择语句 Node tex=nodelist.item(j); // PrintWriter writer=response.getWriter(); String text=tex.getFirstChild().getNodeValue(); System.out.println(text); PrintWriter writer=response.getWriter(); writer.println(text); }else{ System.out.println("not a node type"); } } } } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
[NOTE]
那么能不能用API生成一个无空格的XML文件,而所有对XML的操作都通过这个API来进行?当然可以,你可以自己定义一个XML解析工具类。XML的核心功能就是增加和删除。
对子元素的编辑可以看成一次删除和一次增加。这就是下面我要说的。
XMLtools—自定义的解析工具类
这个自定义的解析工具类,其实,对于XML解析的封装还不是太好,它并不能实现以下工具类使用者以下需求:一次性级联删除
直接编辑
空格异常的安全控制
属性操作(可以使用DOM API实现,工具类并不与DOM有任何冲突)
但是,我认为它依然不失为一个简单有效的API。
Utility
这个工具类具有处理异常的能力,使用方式如下:String Userurl=""; XMLtools tool=new XMLtools(Userurl); //获得根元素 Element root=tool.getRootElement(); Element a=tool.getDocument.createElement("tag"); //不要插入空白元素,因此a要加上文本元素 a.setTextContent("oneslide"); //自动保存 tool.addElement(a,root);
API @javadoc
获得XML的根元素
public Element getRootElement()
增加元素
public void addElement(Node ele,Element parent)
删除元素
public void removeElement(Node ele,Element parent)
PS:
不要插入空白文本节点,比如
<tag></tag>,
但是可以插入
<tag><a></a></tag>或
<tag>xxx</tag>
这是org.w3c.dom的内在问题
Code
import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.xml.sax.SAXException; public class XMLtools { public XMLtools(String url) { super(); this.url = url; this.setDocument(url); this.factory=TransformerFactory.newInstance(); try { this.transform=factory.newTransformer(); domsource=new DOMSource(this.getDocument()); sresult=new StreamResult(url); } catch (TransformerConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private String url;//file url private Document document; private TransformerFactory factory; private Transformer transform; private DOMSource domsource; private StreamResult sresult; private void save(){ try { transform.transform(domsource, sresult); } catch (TransformerException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void addElement(Node ele,Element parent){ //可能会出错误 @see 错误排除 parent.appendChild(ele); try { transform.transform(domsource, sresult); } catch (TransformerException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void removeElement(Node ele,Element parent){ parent.removeChild(ele); domsource.setNode(parent); try { transform.transform(domsource,sresult); } catch (TransformerException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public Element getRootElement(){ return this.document.getDocumentElement(); } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } private Document getDocument() { return document; } private void setDocument(Document document) { this.document = document; } private void setDocument(String url){ DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); try { DocumentBuilder builder=factory.newDocumentBuilder(); Document docu=builder.parse(url); this.setDocument(docu); }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(); } } }
相关文章推荐
- Google Weather API返回XML的SAX和DOM解析当中遇到的问题及解决
- 用 jdom 解析 xml 文件时如何解决中文问题?如何解析?
- boost.property_tree解析xml的帮助类以及中文解析问题的解决
- 解决IE中无法用jquery解析xml使用find的问题
- 关于利用Jsoup解析HTML中 ;变成非传统空格或乱码问题解决方法
- android 在XML解析解决乱码问题
- 解决dom4j无法解析xml命名空间的问题
- Microsoft VBScript 运行时错误 错误 '800a01fb' 出现一个意外错误: 'XMLDom.createNode' 问题解决
- 解析xml的问题未解决
- java解析XML之DOM解析和SAX解析(包含CDATA的问题)
- java.lang.AbstractMethodError: org.apache.xerces.dom.DocumentImpl.setXmlVersion问题解决方法
- 解决NSXmlParser无法解析非utf-8编码的XML问题的方法
- 一个ios工程相关的配置小问题解决介绍,gdata xml解析相关
- 解决Js解析xml浏览器不兼容问题及省市区三级联动实现
- dom解析xml之中文乱码问题
- 关于利用Jsoup解析HTML中&nbsp;变成非传统空格或乱码问题解决方法
- Python的xml.dom.mindom在处理CDATA时候把空格解析为textnode
- 在Resin3下配置SpringSide的HelloWorld示例程序碰到的问题和解决方法(说白了还是resin3.0解析xml问题)
- cocos2d-x 3.0 使用Sax解析xml文档(解决中文显示问题)
- boost.property_tree解析xml的帮助类以及中文解析问题的解决(转)