根据自己debug调试,我觉得对自带的DOM解析有三点需要注意
- DOM将回车(换行符)和节点内容(Value)都是作为节点来解析的。因此会导致一个节点如果没有内容或者节点里面直接是子节点的话也会有内容,不过是"\n"和"\t"组合成的。例:
<root> </root> 或者 <root> <a>sss</a> </root>
在这种情况下会直接输出为:<root> </root> 或者 <root> <a> sss </a> </root>
- 因为第一点,DOM将节点进行了分类,主要是有两类:TEXT_NODE ,ELEMENT_NODE,通过对节点的类型判断,可以很好的解析和过滤所有的节点。
- DOM在获取TETX_NODE类型的节点的内容时,如果是回车(换行符),解析后的内容是由一个或多个的"\n","\t"组成的字符串,而内容(Value)节点解析后的则就是其值,不含"\n","\t"。
正确的例子代码如下:
public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException{
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = docBuilder.parse(new File("books.xml"));
printXmlHeader(doc.getXmlVersion(), doc.getXmlEncoding());
printXml(doc.getDocumentElement(), 0);
}
/**
* 输出xml头
* @param version
* @param encode
*/
private static void printXmlHeader(String version, String encode){
System.out.println("<?xml version=\"" + version + "\" encoding=\"" + encode + "\">");
}
/**
* 输出xml的内容
* @param ele 为节点对象
* @param depth 为节点深度
*/
private static void printXml(Element ele, int depth){
//根据xml子节点的深度进行缩进
printTabWithXmlDepth(depth);
String tagName = ele.getTagName();
System.out.print("<" + tagName);
//输出属性
if(ele.hasAttributes()){
NamedNodeMap map = ele.getAttributes();
for(int index = 0; index < map.getLength(); index++){
Node node = map.item(index);
System.out.print(" " + node.getNodeName() + "=\"" + node.getNodeValue() + "\"");
}
}
System.out.println(">");
//输出该节点的子节点以及内容
if(ele.hasChildNodes()){
NodeList nodeList = ele.getChildNodes();
for(int index = 0; index <nodeList.getLength(); index++){
Node node = nodeList.item(index);
//判断该子节点是否也是一个节点
if(node.getNodeType() == Node.ELEMENT_NODE){
printXml((Element)node, depth+1);
}else if(node.getNodeType() == Node.TEXT_NODE){
String value = node.getNodeValue();
//DOM在获取TETX_NODE类型的节点的内容时,如果是回车(换行符),解析后的内容是由一个或多个的"\n","\t"组成的字符串,而内容(Value)节点解析后的则就是其值,不含"\n","\t"。
value = value.replaceAll("\n", "").replaceAll("\r", "").trim();
if(!"".equals(value)){
printTabWithXmlDepth(depth+1); //由于内容需要在当前节点的情况下进行缩进
//System.out.print(node.getParentNode().getNodeName() + "="); //输出当前node的名字
System.out.println(value);
}
}
}
}
//收尾,如</root>
printTabWithXmlDepth(depth);
System.out.println("</" +tagName + ">");
}
/**
* 缩进
* @param depth
*/
private static void printTabWithXmlDepth(int depth){
for(int i = 0; i < depth; i++){
System.out.print("\t");
}
}
输出结果如下:
<?xml version="1.0" encoding="UTF-8"> <root> ssss <books> <book id="1" name="中国近现代史"> <author> 张三 </author> <publisTime> 2010-9-20 </publisTime> </book> <book id="2" name="世界历史"> <author> Rose </author> <publisTime> 2001-12-10 </publisTime> </book> </books> </root>