解析xml文件
今天的工作很简单,基本与目前开发的项目无关,主要是将一个xml文件解析,提取内容拼接成sql语句。
难点在于里面的层级比较多,如果靠以下的语句一层一层的读取,将嵌套多层for循环,影响效率,且容易读取出错。
//读取外层Entity
Element elementRootElement = (Element) entityRootNode;
NodeList entityRoot = elementRootElement.getElementsByTagName("Entity");
for(int j = 0; j < entityRoot.getLength(); j++){
...
}
后来想出来的办法是将要解析的节点所有从上级节点开始将其读取封装到List中,再解析。
如下:
/**
* 读取指定目录下的所有entity
*
* @param application 指定目录
* @return 将读取到的entity存储到List中,返回集合
*/
private List<NodeList> getAllEntity(NodeList application){
List<NodeList> nodeLists = new ArrayList<>();
for(int i = 0; i < application.getLength(); i++) {
Node entityRootNode = application.item(i);
Element elementRootElement = (Element) entityRootNode;
//读取外层Entity
NodeList entityRoot = elementRootElement.getElementsByTagName("Entity");
for(int j = 0; j < entityRoot.getLength(); j++) {
Node fileNode = entityRoot.item(j);
Element fileElement = (Element) fileNode;
//读取file节点
NodeList file = fileElement.getElementsByTagName("file");
for(int k = 0; k < file.getLength(); k++) {
Node entityNode = file.item(k);
Element entityElement = (Element) entityNode;
if(null != entityElement) {
//读取Entity节点
NodeList entity = entityElement.getElementsByTagName("Entity");
nodeLists.add(entity);
}
}
}
}
return nodeLists;
}
对节点集合进行操作
for(NodeList entity : nodeLists){
for (int x = 0; x < entity.getLength(); x++) {
...
}
}
以上该种反人类的办法被嘲笑了。经过指点使用了XPath读取绝对路径的节点。
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
//将xml文件读到Document
Document doc = db.parse(filePath + fileName);
Element root = doc.getDocumentElement();
XPath xPath = XPathFactory.newInstance().newXPath();
//注意,中间的三个点省略仅为展示用,实际要详细写出中间的路径
NodeList nodes = (NodeList)xPath.evaluate("/import/applications/.../Entity", root, XPathConstants.NODESET);
for (int i = 0, j = nodes.getLength(); i < j; i++) {
...
}
反思一下,目前不足依旧是自己对一些接口、工具类不了解,书看得少了。要多学习,学习才会进步,才能超过目前能对我进行指导的前辈。
以及今天遇到了一个问题,本来不是使用document工厂类进行解析,因为这种方法比较占用内存。导入了dom4j的jar包准备使用这个插件,解析速度快,效率高。然而遇到了部分功能与gradle7.0不兼容的问题,目前无法解决。先记下来,以后解决。