2013-04-23 114 views
0

我有這個單行xml文件(不縮進和新行),如下Java的DOM解析器不解析一行XML

<?xml version="1.0" encoding="UTF-8"?> 
    <Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.054.001.03" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:camt.054.001.03 
camt.054.001.03.xsd"> 
    <BkToCstmrDbtCdtNtfctn><GrpHdr><MsgId>0000000006</MsgId> 
<CreDtTm>2013-04- 
    16T14:38:00</CreDtTm> 
</GrpHdr> 
</BkToCstmrDbtCdtNtfctn></Document> 

我使用這個Java DOM解析器程序來解析和檢索值

import java.io.File; 
import java.util.ArrayList; 
import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 

import org.w3c.dom.Document; 
import org.w3c.dom.Element; 
import org.w3c.dom.NodeList; 

public class GetNodeValues { 
    static String value = null; 
    static ArrayList alist = null; 

    /****************** GET XPATH FOR EACH TAG **************************************/ 

    public static String getXPath(Element elemnt) { 
     String xpath = null; 
     String curNode = elemnt.getNodeName(); 
     ArrayList<String> al = new ArrayList<String>(); 
     al.add(curNode); 
     // al.add(parNode); 
     while (!elemnt.getParentNode().getNodeName().equals("#document")) { 
      al.add(elemnt.getParentNode().getNodeName()); 
      elemnt = (Element) elemnt.getParentNode(); 
     } 

     for (int i = al.size() - 1; i >= 0; i--) { 
      xpath = xpath + "/" + al.get(i); 
     } 
     return xpath.replaceAll("null", ""); 
    } 

    /******************************************************************************************/ 

    /**************************** GET TAG NAMES AND VALUES ***********************/ 

    public static ArrayList getValues() { 
     try { 

      alist = new ArrayList(); 
      String xmlFile = "C:/Users/Administrator/Desktop/sample2.xml"; 
      File file = new File(xmlFile); 
      if (file.exists()) { 

       // Create a factory 
       DocumentBuilderFactory factory = DocumentBuilderFactory 
         .newInstance(); 
       // Use the factory to create a builder 
       DocumentBuilder builder = factory.newDocumentBuilder(); 
       Document doc = builder.parse(xmlFile); 

       doc.getDocumentElement().normalize(); 

       // Get a list of all elements in the document 
       NodeList list = doc.getElementsByTagName("*"); 

       for (int i = 0; i < list.getLength(); i++) { 
        // Get element 
        Element element = (Element) list.item(i); 
        String nodnam = element.getNodeName(); 


        if (element.getChildNodes().getLength() > 0) // then it has 
                    // text 
        { 
         String val = element.getChildNodes().item(0) 
           .getNodeValue(); 
         if (val.startsWith("\n")) { // Discarding pseudo nodes 

         } else { 
          value = nodnam + " > " + val + " > " 
            + getXPath(element); // print node names and 
                  // values 
          System.out.println(value); 
          alist.add(value); 
         } 
        } 
       } 
      } else { 
       System.out.print("File not found!"); 
      } 
     } catch (Exception e) { 
      System.exit(1); 
     } 

     return alist; 
    } 

    /********************************************************************************************/ 

    /************************** MAIN METHOD **********************************************/ 
    public static void main(String[] args) { 
     System.out.println(getValues()); 

    } 
} 

而且它沒有打印任何值。但是如果我編輯XML文件,並添加縮進和新行這樣

<?xml version="1.0" encoding="UTF-8"?> 
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.054.001.03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:camt.054.001.03 camt.054.001.03.xsd"> 
    <BkToCstmrDbtCdtNtfctn> 
     <GrpHdr> 
      <MsgId>0000000006</MsgId> 
      <CreDtTm>2013-04-16T14:38:00</CreDtTm> 
     </GrpHdr> 
    </BkToCstmrDbtCdtNtfctn> 
</Document> 

然後我得到像下面

MsgId > 0000000006 > /Document/BkToCstmrDbtCdtNtfctn/GrpHdr/MsgId 
CreDtTm > 2013-04-16T14:38:00 > /Document/BkToCstmrDbtCdtNtfctn/GrpHdr/CreDtTm 

,所以這個問題我不能編輯每一個XML文件作爲無輸出。要處理的文件是巨大的。我在java dom解析器中丟失了什麼?所有我需要的是,該方案應解析和其不具有縮進和換行的xml文件打印值....

回答

2

注意,這樣做:

} catch (Exception e) { 
    System.exit(1); 
} 

你是隱藏例外,而不是能夠看到真正的問題。 打印堆棧跟蹤,至少,如:

} catch (Exception e) { 
    e.printStackTrace(); 
    System.exit(1); 
} 

在這種情況下從該String val = element.getChildNodes().item(0).getNodeValue();var可以爲空。因此,使用以下修補程序應該可以解決此問題:從造成NPE的實際問題

String val = element.getChildNodes().item(0).getNodeValue(); 
if (val != null) { 
    if (val.startsWith("\n")) { // Discarding pseudo nodes 
    } else { 
     value = nodnam + " > " + val + " > " 
      + getXPath(element); // print node names and 
           // values 
     System.out.println(value); 
     alist.add(value); 
    } 
} 
+0

非常感謝丹,添加e.printStackTrace()後,我得到了NullPointerException。然後,我按照你的建議改變了代碼,現在按照它的原則工作。再次感謝.. – 2013-04-23 08:51:33

+0

@AshishBanerjee不客氣。 – dan 2013-04-23 09:24:37

1

除此之外,我認爲有3個不同的問題與您的代碼在這一點:

} catch (Exception e) { 
    System.exit(1); 
    } 

的第一個問題(如@dan所指出的)是您不打印堆棧跟蹤。第二個問題是您正在捕捉Exception。在大多數情況下,這是一個糟糕的主意,因爲除了您可能期望的任何外,您最終還是會捕捉到各種意想不到的異常。只捕獲您期望並可以在當時處理的例外情況會好得多。其餘的人應該被允許傳播。

第三個問題是您打電話給System.exit看似是一種實用方法。這是一對夫婦的原因,一個壞主意:

  • 的方法救助將會使這種方法難以在其他情況下...其中救助是錯誤的做法來使用。

  • 任何調用System.exit的方法對單元測試都會很棘手。如果你沒有采取措施來避免它(例如,使用模擬框架,可以「嘲笑」那個調用),那麼這個方法正在運行,導致運行單元測試的JVM立即停止...。

在我看來,編寫代碼的正確方法是:

  1. 添加任何必要throws條款的getValues()方法聲明,並
  2. try ... catchmain方法...用一些代碼輸出或記錄異常堆棧跟蹤當然。