原生java解析xml的方法提供了两个,DocumentBuilder 和 SAXParser.
试了第一个DOM方法,在解析输出节点过程当中,getNodeName()输出节点名发现多出了几个#text节点。
text.xml
123456
20200115235900
1
2
3
4
5
6
222223
2020-01-14 23:59:00
11
DOM.java
import java.util.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;
public class DOM {
//document解析器工厂
private static DocumentBuilderFactory docBuiFactory = null;
//document解析器能够经过documentBuiderFactory的newDocumentBuilder()函数获取
private static DocumentBuilder docBuilder = null;
//document对象能够经过documentBuilder的newDocumentBuilder()函数获取
private static Document doc = null;
//自定义对象book的集合用来存储xml获取的book对象
private static List books = null;
//静态代码块用来初始化静态属性,只会在类的第一次加载执行一次
static {
try {
//初始化documentBuilderFactory
docBuiFactory = DocumentBuilderFactory.newInstance(); //newInstance经过反射机制建立DocumentBuilderFactory的实现类
//初始化documentBuilder
docBuilder = docBuiFactory.newDocumentBuilder(); //经过DocumentBuilderFactoryImpl的newDocumentBuilder()函数返回DocumentBuilder对象
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String filterBlankXMl(String xml) {
//校验规则1位有一个空格就开始过滤,若是改成3则三个连续空格才过滤
Pattern p = Pattern.compile("\\s{1,}|\t|\r|\n");
Matcher m = p.matcher(xml);
xml = m.replaceAll("");
System.out.println("接受到的XML:\n" + xml);
return xml;
}
public static List getXml(String fileURL) throws Exception {
//将给定的url的内容解析为一个xml文档,并返回document对象
doc = docBuilder.parse(fileURL);
//按顺序获取xml内全部book元素节点
NodeList IssueList = doc.getElementsByTagName("ldata");
books = new ArrayList();
//遍历books
NodeList ldataList = doc.getElementsByTagName("ldata");//获取全部的ldata节点
//遍历全部的ldata节点
//for(int i = 0;i
Node numbersNode = ldataList.item(0);
//这里只取第一个ldata的节点数据
NodeList numberList = numbersNode.getChildNodes();
for(int j = 0;j
//if(!"#text".equals(numberList.item(j).getNodeName())){
System.out.println(numberList.item(j).getNodeName());
}
// }
return books;
}
public static void main(String[] args) {
String fileURL = "file:///XmlDemo/test.xml";
try {
List list = DOM.getXml(fileURL);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
发现java
System.out.println(numberList.item(j).getNodeName());
输出的结果:dom
#text
issue
#text
date
#text
number
#text
这个***#text***一度让我很迷茫,从检查xml是否写错到检查读取xmk的方法是否有问题,最后仍是善用了搜索引擎😀。ide
缘由主要是使用org.w3c.dom.Node的进行解析的,它会将你的回车也做为一个节点。在你的代码中你打印.getLenth();获得的数值确定比你写的节点要多。
明白了这个缘由就简单多了,脑中出现了两种方法。
1.想办法把xml的回车空行去掉再解析.
既不用改动文件,也不会使getlength()的长度发生变化 正则匹配xml空格换行而后替换:函数
public static String filterBlankXMl(String xml) {
//校验规则1位有一个空格就开始过滤,若是改成3则三个连续空格才过滤
Pattern p = Pattern.compile("\\s{1,}|\t|\r|\n");
Matcher m = p.matcher(xml);
xml = m.replaceAll("");
System.out.println("接受到的XML:\n" + xml);
return xml;
}
public static String readFileByLines(String fileName) {
File file = new File(fileName);
BufferedReader reader = null;
String content = "";
try {
// System.out.println("以行为单位读取文件内容,一次读一整行:");
reader = new BufferedReader(new FileReader(file));
String tempString = null;
int line = 1;
// 一次读入一行,直到读入null为文件结束
while ((tempString = reader.readLine()) != null) {
// 显示行号
// System.out.println("line " + line + ": " + tempString);
content = content + tempString;
line++;
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
}
}
}
return content;
}
String file = filterBlankXMl(readFileByLines(filepath));
//将格式化后的xml String 转换成 InputStream 用parse解析
doc = docBuilder.parse(new ByteArrayInputStream(file.getBytes()));
2.输出节点时判断NodeName为#text则不进行处理否输出.
虽然输出正确,到getlength的长度仍是变了测试
for ...{
if(!"#text".equals(numberList.item(j).getNodeName())){
//处理过滤的节点
System.out.println(numberList.item(j).getNodeName());
}
}
固然还能够使用dom4j等其余第三方jarui