2013-08-06 179 views
0

所以縮進所有的XML標籤,我有以下XML文件 樣本:迭代通過使用Java

<Entry> 
     <ns0:entity-Person> 
     <ns0:Cell>333-333-3333</ns0:CellPhone> 
     <ns0:DOB>1970-01-01T01:00:00-05:00</ns0:DateOfBirth> 
     <ns0:FN>Raymond</ns0:FirstName> 
     <ns0:Gender>M</ns0:Gender> 
     </ns0:entity-Person> 
     <ns0:EmailAddress1>[email protected]</ns0:EmailAddress1> 
     <ns0:EmailAddress2>[email protected]</ns0:EmailAddress2> 
     <ns0:Entry> 
      <ns1:OfficialIDType>SSN</ns1:OfficialIDType> 
      <ns1:OfficialIDValue>342-56-8729</ns1:OfficialIDValue> 
     </ns0:Entry> 

.. ..

,我想下面的輸出:

Entry 
    ns0:entity-Person 
     ns0:CellPhone 
     ns0:DateOfBirth 
     ns0:FN 
     ns0:Gender 
    ns0:EmailAddress1 
    ns0:EmailAddress2 
    ns0:Entry 
     ns1:OfficialIDType 
     ns1:OfficialIDValue 

所以,基本上,我想爲每個父節點的子節點有一個縮進(「\ t」在java中)。

至於現在,我有以下代碼(遞歸):

public static void main(String[] args) throws SAXException, IOException, 
     ParserConfigurationException, TransformerException { 

    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); 
    Document document = docBuilder.parse(new File("C:\\sub.xml")); 

    parseTheTags(document.getDocumentElement()); 
} 

public static void parseTheTags(Node node) { 
    System.out.println(node.getNodeName()); 

    NodeList nodeList = node.getChildNodes(); 
    for (int i = 0; i < nodeList.getLength(); i++) { 
     Node currentNode = nodeList.item(i); 
     if (currentNode.getNodeType() == Node.ELEMENT_NODE) { 
      parseTheTags(currentNode);  
     } 
    } 
} 

我也知道如何做到這一點沒有遞歸,但它是我無法做到的縮進。 我知道它會在代碼的某個地方發生一些小的變化,但我已經花了相當長的時間在這個上,沒有用。

這就是我認爲stackoverflow可能可以幫助我!

編輯的代碼:現在,附加選項卡每個子節點:輸出有問題,雖然

public class NewParseXMLTags { 

    public static void main(String[] args) throws SAXException, IOException, 
     ParserConfigurationException, TransformerException { 

    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); 

    Document document = docBuilder.parse(new File("C:\\Users\\parasv1\\Desktop\\Self\\sub.xml")); 

    StringBuilder tmp = new StringBuilder(); 

    tmp.append(""); 
    parseTheTags(tmp, document.getDocumentElement()); 

} 

public static void parseTheTags(StringBuilder indentLevel, Node node) { 

    StringBuilder indent = new StringBuilder(); 

System.out.println(indentLevel+node.getNodeName()); 


NodeList nodeList = node.getChildNodes(); 
for (int i = 0; i < nodeList.getLength(); i++) { 
    Node currentNode = nodeList.item(i); 

    if (currentNode.getNodeType() == Node.ELEMENT_NODE) { 
     if (currentNode.hasChildNodes()) 
     { 
      indent.append("\t"); 
      parseTheTags(indent, currentNode);  
      }  
     } 
    } 
    } 
} 

答案找到: 於是,經過一些好的想法和Sbodd幫助下,我找到了修復:非常簡單!

public class ParseXML { 

    public static void main(String[] args) throws SAXException, IOException, 
     ParserConfigurationException, TransformerException { 

    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); 

    Document document = docBuilder.parse(new File("C:\\Users\\parasv1\\Desktop\\Self\\sub.xml")); 

    String tmp = new String(); 

    tmp = ""; 
    parseTags(tmp, document.getDocumentElement()); 

} 

    public static void parseTags (String indentLevel, Node node) { 
      //print out node-specific items at indentLevel 
     System.out.println(indentLevel+node.getNodeName()); 
      String childIndent = indentLevel + "\t"; 


      NodeList nodeList = node.getChildNodes(); 
      for (int i = 0; i < nodeList.getLength(); i++) { 
       Node n = nodeList.item(i); 
       if (n.getNodeType() == Node.ELEMENT_NODE) { 

      parseTags(childIndent, n); 
      } 
     } 


    }   

任何與他的幫助將不勝感激!

+0

任何人都可以幫忙嗎?我仍然沒有任何幫助來解決我的問題! :( – VictorCreator

回答

1

縮寫形式是:添加一個indentLevel參數parseTheTags。在每次遞歸調用時,遞增indentLevel,並使用它來格式化輸出。

編輯更新代碼: 您實際上並沒有遞歸使用indentLevel;您傳遞給子調用的值indent與變量indentLevel變量完全無關。此外,您可能不希望將StringBuilder用於遞歸深度變量 - 對其進行更改會在遞歸調用過程中上下傳播。

你的基本的通話結構應該大致如下

public void parseTags (String indentLevel, Node node) { 
    //print out node-specific items at indentLevel 
    String childIndent = indentLevel + "\t"; 

    for (Node n : /*whatever nodes you're recursing to*/) { 
    parseTags(childIndent, n); 
    } 
} 

這是一個非常標準的遞歸結構。在當前節點上採取行動,增加遞歸深度計數器的值,並根據需要進行遞歸調用。

+0

我已經試過了。我使用了一個StringBuilder,並且我嘗試爲每個遞歸調用附加一個「\ t」。 但是,該方法不起作用! (可能是,我得到的都是錯誤的,如果你可以更具描述性,這可能會有所幫助,例如,一些示例代碼或其他東西 – VictorCreator

+0

如果你用目前爲止的代碼更新你的問題,我可能會看一看 - 到目前爲止,你所得到的樣本根本不會產生任何輸出。 – Sbodd

+0

是的,我已經將代碼添加到了上面的問題中。請檢查並告訴我是否在哪裏出錯! – VictorCreator

0

因此,最終的代碼看起來應該像

public static void main(String[] args) throws SAXException, IOException, 
     ParserConfigurationException, TransformerException { 

    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); 
    Document document = docBuilder.parse(new File("C:\\sub.xml")); 
    Transformer t = TransformerFactory.newInstance().newTransformer(); 
    t.setOutputProperty(OutputKeys.INDENT, "yes"); 
    t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); 
    ByteArrayOutputStream s = new ByteArrayOutputStream(); 
    t.transform(new DOMSource(document),new StreamResult(s)); 
    System.out.println(new String(s.toByteArray())); 
} 
+0

對不起,但是這是怎麼回事?我不完全確定把這部分插入到我的代碼中的位置 – VictorCreator

+0

只需將它放在行後 DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docBuilderFactory。newDocumentBuilder(); –

+0

我把它放在該行後面,正如你所建議的那樣_,但是這不會改變輸出中的任何東西! – VictorCreator