您的位置:首页 > 其它

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();
}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: