java DOM解析xml文件出現#text節點解決方案

原生java解析xml的方法提供了兩個,DocumentBuilder 和 SAXParser.

試了第一個DOM方法,在解析輸出節點過程當中,getNodeName()輸出節點名發現多出了幾個#text節點。

text.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- xml解析測試文件 -->
<LData>    
  <ldata>       
  <issue>123456</issue>           
  <date>20200115235900</date>        
  <nil></nil>       
  <nil2> </nil2>       
  <numbers>       
    <number>1</number>          
    <number>2</number>        
    <number>3</number>        
    <number>4</number>        
    <number>5</number>        
    <number>6</number>             
   </numbers>   
 </ldata>   
 <ldata>       
   <issue>222223</issue>            
   <date>2020-01-14 23:59:00</date>        
   <numbers>  
       <number>11</number>        
   </numbers>   
  </ldata>
 </LData>

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<Book> 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<Book> getXml(String fileURL) throws Exception {
        //將給定的url的內容解析爲一個xml文檔,並返回document對象
        doc = docBuilder.parse(fileURL);
        //按順序獲取xml內全部book元素節點
        NodeList IssueList = doc.getElementsByTagName("ldata");
        books = new ArrayList<Book>();
        //遍歷books
        NodeList ldataList = doc.getElementsByTagName("ldata");//獲取全部的ldata節點
        //遍歷全部的ldata節點
        //for(int i = 0;i<ldataList.getLength();i++) {
            Node numbersNode = ldataList.item(0);
            //這裏只取第一個ldata的節點數據
            NodeList numberList = numbersNode.getChildNodes();
            for(int j = 0;j<numberList.getLength();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<Book> 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

相關文章
相關標籤/搜索