0

所以,我有以下 XML 文件示例:

<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>email1@email.com</ns0:EmailAddress1>
      <ns0:EmailAddress2>email2@email.com</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

所以,基本上,我想为每个父节点的子节点缩进(Java 中的“\t”)。

就目前而言,我有以下代码(带递归):

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);
          }
        }


    }           

对他的任何帮助将不胜感激!

4

2 回答 2

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);
  }
}

这是一个非常标准的递归结构。在当前节点上执行操作,增加递归深度计数器的值,并根据需要进行递归调用。

于 2013-08-06T20:23:36.790 回答
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()));
}
于 2013-08-06T18:50:26.180 回答