简体   繁体   English

如何使用 Java 从 XML 文档中获取所有节点名称的列表

[英]How to get list of All Node Names from XML document using Java

import java.io.StringReader;

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;
import org.xml.sax.InputSource;

public class comparexmls {
  public static void main(String[] argv) throws Exception {
    InputSource is = new InputSource();
    is.setCharacterStream(new StringReader(xmlRecords));

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();

    Document doc = db.parse(is);

    NodeList list = doc.getChildNodes();
    //System.out.println(doc.getChildNodes().item(2));
    for (int i = 0; i < list.getLength(); i++) {
      if (list.item(i) instanceof Element) {
        Element root = (Element) list.item(i);
        System.out.println(root.getNodeName());

        break;
      }
    }
  }

  static String xmlRecords = 
      "<Search.UDB.OUT TraceId=\"1234\">\r\n" + 
      "    <Response>Success</Response>\r\n" + 
      "    <Status>\r\n" + 
      "        <System Name=\"X\">\r\n" + 
      "            <Code>00</Code>\r\n" + 
      "            <Message></Message>\r\n" + 
      "        </System>\r\n" + 
      "        <System Name=\"Y\">\r\n" + 
      "            <Code>00</Code>\r\n" + 
      "            <Message></Message>\r\n" + 
      "        </System>\r\n" + 
      "        <System Name=\"Z\">\r\n" + 
      "            <Code>00</Code>\r\n" + 
      "            <Message></Message>\r\n" + 
      "        </System>\r\n" + 
      "    </Status>\r\n" + 
      "    <NumberFound>1</NumberFound>\r\n" + 
      "    <AccountList>\r\n" + 
      "        <Account>\r\n" + 
      "            <AccountNumber>XXXXXXXXXXXX</AccountNumber>\r\n" + 
      "            <CorpNo>XX</CorpNo>\r\n" + 
      "            <Name>Chandra</Name>\r\n" + 
      "            <AddressLine1>100 MAIN ST</AddressLine1>\r\n" + 
      "            <AddressLine2>ANYTOWN</AddressLine2>\r\n" + 
      "            <AddressLine3> GA 123456789</AddressLine3>\r\n" + 
      "            <Block />\r\n" + 
      "            <Reclass />\r\n" + 
      "            <EmbossLine4 />\r\n" + 
      "            <Phone>1234567890</Phone>\r\n" + 
      "        </Account>\r\n" + 
      "    </AccountList>\r\n" + 
      "</Search.UDB.OUT>";

}

I am getting Search.UDB.OUT only.. How to iterate all the parent and childnodes..我只得到 Search.UDB.OUT .. 如何迭代所有父节点和子节点..

Take a look at the XmlSlurper class in http://stefanfrings.de/bfUtilities/bfUtilities.zip .看看http://stefanfrings.de/bfUtilities/bfUtilities.zip 中的 XmlSlurper class It's a recursive algorithm.这是一个递归算法。

It reads the whole XML into a simple flat HashMap collecting all element names in the format:它将整个 XML 读取到一个简单的平面 HashMap 中,以以下格式收集所有元素名称:

Search.UDB.OUT.TraceId
Search.UDB.OUT.Response
Search.UDB.OUT.Status.System.Name
...

Source code of that class: class 的源代码:

package de.stefanfrings.parsing;

import de.stefanfrings.container.ConvertingHashMap;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashSet;
import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class XmlSlurper
{

    public static ConvertingHashMap parse(String xmlDocument) throws ParserConfigurationException, SAXException, IOException
    {
        ConvertingHashMap targetMap=new ConvertingHashMap();
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder builder = factory.newDocumentBuilder();
        InputSource is = new InputSource(new StringReader(xmlDocument));
        Document doc=builder.parse(is);
        Element rootElement=doc.getDocumentElement();
        collectData(rootElement,rootElement.getNodeName().toLowerCase(),targetMap);
        return targetMap;
    }


    /** Collect the content of one element */
    private static void collectData(Element element, String currentPath, ConvertingHashMap targetMap)
    {
        if (element==null)
        {
            return;
        }        
        // Collect all attributes of this ode
        NamedNodeMap attributes = element.getAttributes();
        if (attributes!=null)
        {
            for (int i=0; i<attributes.getLength(); i++)
            {
                Attr attribute = (Attr) attributes.item(i);
                String name = attribute.getLocalName();
                if (name==null)
                {
                    name = attribute.getNodeName();
                }
                String value = attribute.getNodeValue();
                targetMap.put(currentPath+"."+name.toLowerCase(), value);
            }
        }
        // Collect all child elements recursively
        boolean hasChildren=false;
        NodeList children=element.getChildNodes();
        if (children!=null)
        {
            int count=0;
            for (int i=0; i<children.getLength(); i++)
            {
                Node node=children.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE)
                {
                    hasChildren=true;
                    Element child = (Element)children.item(i);
                    String name=child.getLocalName();
                    if (name==null)
                    {
                        name=child.getNodeName();
                    }
                    String key=currentPath+"."+name.toLowerCase();
                    // do we have already a children with same name?
                    if (targetMap.containsKey(key))
                    {
                        // duplicate the first (existing) item
                        if (count==0)
                        {
                            // Make a copy of the first element and all of its sub elements by inserting the number 0
                            Set<String> keySet = new HashSet<>();
                            keySet.addAll(targetMap.keySet());
                            for (String k:keySet)
                            {
                                if (k.equals(key) || k.startsWith(key+"."))
                                {
                                   String existing=targetMap.get(k);
                                   targetMap.put(k.replace(key,key+"0"),existing);
                                }
                            }
                        }
                        // add new item
                        collectData(child,key+String.valueOf(++count),targetMap);
                    }
                    else
                    {
                        collectData(child,key,targetMap);
                    }
                }
            }
        }
        if (!hasChildren)
        {
            // Get the text content
            String text=element.getTextContent();
            targetMap.put(currentPath, text);
        }
        else
        {
            targetMap.put(currentPath, ""); // no text
        }
    }
}

You may replace the ConvertingHashMap by a regular HashMap.您可以将 ConvertingHashMap 替换为常规的 HashMap。 The difference is that the ConvertingHash has methods like getInteger() and getDate() .不同之处在于 ConvertingHash 具有getInteger()getDate()等方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM