2013-08-06 149 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