DOM解析XML解决空格问题

DOM解析XML问题

BUG:
之所以称之为bug,是因为我认为DOM应该忽略非元素包括内的空白,而把空白也当成一个子节点。解决办法是判断子节点是否为元素节点,但是这会让代码感觉非常难受,所以应该在XML的可读性和程序的简洁性中做出选择。
成功解析XML两种方案:

  1. 删除所有空格
  2. 增加判断是否为元素节点

XML


<users>
    
     <customer>
        <id>1id>
        <name>oneslidename> 
        <password>123456789password>                      
        <contact>[email protected]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;ifor(int j=0;jif(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解析的封装还不是太好,它并不能实现以下工具类使用者以下需求:

  1. 一次性级联删除
  2. 直接编辑
  3. 空格异常的安全控制
  4. 属性操作(可以使用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:

不要插入空白文本节点,比如,
但是可以插入xxx
这是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();
        }

    }

}

你可能感兴趣的:(Java)