2014-07-02 59 views
0

回到我試圖解析以下XML:空/空節點從getChildNodes

<?xml version="1.0" encoding="UTF-8"?> 
<docusign-cfg> 
    <tagConfig> 
     <tags> 
      <approve>approve</approve> 
      <checkbox>checkbox</checkbox> 
      <company>company</company> 
      <date>date</date> 
      <decline>decline</decline> 
      <email>email</email> 
      <emailAddress>emailAddress</emailAddress> 
      <envelopeID>envelopeID</envelopeID> 
      <firstName>firstName</firstName> 
      <lastName>lastName</lastName> 
      <number>number</number> 
      <ssn>ssn</ssn> 
      <zip>zip</zip> 
      <signHere>signHere</signHere> 
      <checkbox>checkbox</checkbox> 
      <initialHere>initialHere</initialHere> 
      <dateSigned>dateSigned</dateSigned> 
      <fullName>fullName</fullName> 
     </tags> 
    </tagConfig> 
</docusign-cfg> 

我想讀的名稱或在<tags>標籤每個標籤的內容。我可以用下面的代碼這樣做:

public String[] getAvailableTags() throws Exception 
{ 

    String path = "/docusign-cfg/tagConfig/tags"; 
    XPathFactory f = XPathFactory.newInstance(); 
    XPath x = f.newXPath(); 
    Object result = null; 
    try 
    { 
     XPathExpression expr = x.compile(path); 
     result = expr.evaluate(doc, XPathConstants.NODE); 
    } 
    catch (XPathExpressionException e) 
    { 
     throw new Exception("An error ocurred while trying to retrieve the tags"); 
    } 

    Node node = (Node) result; 
    NodeList childNodes = node.getChildNodes(); 
    String[] tags = new String[childNodes.getLength()]; 
    System.out.println(tags.length); 
    for(int i = 0; i < tags.length; i++) 
    { 
     String content = childNodes.item(i).getNodeName().trim().replaceAll("\\s", ""); 

     if(childNodes.item(i).getNodeType() == Node.ELEMENT_NODE && 
       childNodes.item(i).getNodeName() != null) 
     { 
      tags[i] = content; 
     } 
    } 

    return tags; 
} 

一番搜索後,我發現,解析它這樣導致它讀取節點之間的空白/標籤會導致被解讀爲子女的空格。在這種情況下,空格被認爲是<tags>的孩子。

我的輸出:

37 
null 
approve 
null 
checkbox 
null 
company 
null 
date 
null 
decline 
null 
email 
null 
emailAddress 
null 
envelopeID 
null 
firstName 
null 
lastName 
null 
number 
null 
ssn 
null 
zip 
null 
signHere 
null 
checkbox 
null 
initialHere 
null 
dateSigned 
null 
fullName 
null 

37是它在<tags>發現 一切低於37是tag陣列的內容的節點的數目。

儘管我檢查了null,這些null元素如何被添加到tag數組?

回答

0

我認爲這是因爲標籤的索引。 if檢查還會跳過索引。所以即使值沒有被插入,它也會導致null。使用單獨的索引標籤陣列

int j = 0; 
for(int i = 0; i < tags.length; i++) 
{ 
    String content = childNodes.item(i).getNodeName().trim().replaceAll("\\s", ""); 

    if(childNodes.item(i).getNodeType() == Node.ELEMENT_NODE && 
     childNodes.item(i).getNodeName() != null) 
    { 
     tags[j++] = content; 
    } 
} 

由於要省略一些子節點,創建整個子節點長度的陣列可能導致存儲器的浪費。您可以改用List。如果你對字符串數組很特別,你可以稍後將它轉換爲數組。

public String[] getAvailableTags() throws Exception 
{ 
    String path = "/docusign-cfg/tagConfig/tags"; 
    XPathFactory f = XPathFactory.newInstance(); 
    XPath x = f.newXPath(); 
    Object result = null; 
    try 
    { 
     XPathExpression expr = x.compile(path); 
     result = expr.evaluate(doc, XPathConstants.NODE); 
    } 
    catch (XPathExpressionException e) 
    { 
     throw new Exception("An error ocurred while trying to retrieve the tags"); 
    } 

    Node node = (Node) result; 
    NodeList childNodes = node.getChildNodes(); 
    List<String> tags = new ArrayList<String>(); 
    for(int i = 0; i < tags.length; i++) 
    { 
     String content = childNodes.item(i).getNodeName().trim().replaceAll("\\s", ""); 

     if(childNodes.item(i).getNodeType() == Node.ELEMENT_NODE && 
      childNodes.item(i).getNodeName() != null) 
     { 
      tags.add(content); 
     } 
    } 

    String[] tagsArray = tags.toArray(new String[tags.size()]); 
    return tagsArray; 
} 
+0

當然'if'語句的工作原理,我只是沒有意識到特定的數組索引沒有被初始化,因爲它被跳過了。 我不知道爲什麼我決定使用常規數組。我已經把它改成了ArrayList。 – braab

+0

默認情況下,數組將爲空。沒有初始化發生。但是如果你願意,你可以用一些默認值填充一個數組。使用'java.util.Arrays.fill()'方法。 –

0

標籤數組的內容默認爲null。

因此,它不是一個元素如何變爲null的情況,它是保留爲null的情況。

爲了證實這一點,添加以下else塊這樣的:

if(childNodes.item(i).getNodeType() == Node.ELEMENT_NODE && 
      childNodes.item(i).getNodeName() != null) 
    { 
     tags[i] = content; 
    } else { 
     tags[i] = "Foo Bar"; 
    } 

您現在應該看到「富酒吧」,而不是空。

這裏的一個更好的解決方案是使用ArrayList,並將標籤添加到它而不是使用數組。那麼你不需要跟蹤索引,減少這類錯誤的機會。