2011-03-22 18 views
57

जावा में सभी DOM तत्वों के माध्यम से पुन: प्रयास करने का सबसे प्रभावी तरीका क्या है?जावा: org.w3c.dom.Document में सभी तत्वों को फिर से चलाने के लिए सबसे प्रभावी तरीका?

कुछ ऐसा है लेकिन वर्तमान org.w3c.dom.Document पर प्रत्येक एकल डीओएम तत्वों के लिए?

for(Node childNode = node.getFirstChild(); childNode!=null;){ 
    Node nextChild = childNode.getNextSibling(); 
    // Do something with childNode, including move or delete... 
    childNode = nextChild; 
} 
+0

नोड.getChildNodes का पुनरावर्ती आमंत्रण? http://download.oracle.com/javase/6/docs/api/org/w3c/dom/Node.html#getChildNodes%28%29 –

उत्तर

102

मूल रूप से आप दो सभी तत्वों से अधिक पुनरावृत्ति करने के लिए तरीके हैं:

1. प्रत्यावर्तन का उपयोग करना (सबसे आम तरीका मुझे लगता है कि):

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("document.xml")); 
    doSomething(document.getDocumentElement()); 
} 

public static void doSomething(Node node) { 
    // do something with the current node instead of System.out 
    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) { 
      //calls this method for all the children which is Element 
      doSomething(currentNode); 
     } 
    } 
} 

2. प्रत्यावर्तन से बचना getElementsByTagName() विधि * के साथ पैरामीटर के रूप में उपयोग:

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("document.xml")); 

    NodeList nodeList = document.getElementsByTagName("*"); 
    for (int i = 0; i < nodeList.getLength(); i++) { 
     Node node = nodeList.item(i); 
     if (node.getNodeType() == Node.ELEMENT_NODE) { 
      // do something with the current element 
      System.out.println(node.getNodeName()); 
     } 
    } 
} 

मुझे लगता है कि ये तरीके दोनों कुशल हैं।
उम्मीद है कि यह मदद करता है।

+10

पुनरावर्ती कार्य को तर्कसंगत फ़ंक्शन के लिए तर्क के रूप में उत्तीर्ण करना, आप इसे बना सकते हैं पूंछ-पुनरावर्ती, जो ढेर अतिप्रवाह से बचने के लिए कंपाइलर द्वारा अनुकूलित किया जाता है। – khachik

+95

मुझे लगता है कि स्टैक ओवरफ़्लो से बचने में बहुत देर हो चुकी है। आप पहले से ही यहाँ हैं – braden

+1

आपको क्या लगता है कि पूरे दस्तावेज़ के लिए नोड सूची का निर्माण कुशल है? इसका मतलब है कि लगभग पूरे दस्तावेज़ की प्रतिलिपि बनाना। या क्या 'आइटम' में अनुक्रमिक कॉल को अनुकूलित करने वाले 'नोडलिस्ट' में छिपा हुआ कुछ प्रकार का देरी मूल्यांकन है? – ceving

32

for (int i = 0; i < nodeList.getLength(); i++)

परिवर्तन

को

for (int i = 0, len = nodeList.getLength(); i < len; i++)

अधिक कुशल होने का। दूसरा तरीका सबसे अच्छा हो सकता है क्योंकि यह एक चापलूसी, अनुमानित स्मृति मॉडल का उपयोग करता है।

+1

टिप्पणी करने के लिए आपको कम से कम 50 प्रतिनिधि स्कोर की आवश्यकता है। मुझे एक ही समस्या थी और जवाब दिया क्योंकि मैं टिप्पणी नहीं कर सका। कुछ अपवित्र सहायता है;) – nyaray

+2

संकलक अनुकूलित नहीं करता ??? :-P – whomaniac

2

मैंने हाल ही में इस समस्या पर भी ठोकर खाई। मेरा समाधान यहाँ है। मैं रिकर्सन से बचना चाहता था, इसलिए मैंने थोड़ी देर लूप का इस्तेमाल किया।

सूची में मनमाने ढंग से स्थानों में जोड़े और हटाए जाने के कारण, मैं LinkedList कार्यान्वयन के साथ गया।

/* traverses tree starting with given node */ 
    private static List<Node> traverse(Node n) 
    { 
    return traverse(Arrays.asList(n)); 
    } 

    /* traverses tree starting with given nodes */ 
    private static List<Node> traverse(List<Node> nodes) 
    { 
    List<Node> open = new LinkedList<Node>(nodes); 
    List<Node> visited = new LinkedList<Node>(); 

    ListIterator<Node> it = open.listIterator(); 
    while (it.hasNext() || it.hasPrevious()) 
    { 
     Node unvisited; 
     if (it.hasNext()) 
     unvisited = it.next(); 
     else 
     unvisited = it.previous(); 

     it.remove(); 

     List<Node> children = getChildren(unvisited); 
     for (Node child : children) 
     it.add(child); 

     visited.add(unvisited); 
    } 

    return visited; 
    } 

    private static List<Node> getChildren(Node n) 
    { 
    List<Node> children = asList(n.getChildNodes()); 
    Iterator<Node> it = children.iterator(); 
    while (it.hasNext()) 
     if (it.next().getNodeType() != Node.ELEMENT_NODE) 
     it.remove(); 
    return children; 
    } 

    private static List<Node> asList(NodeList nodes) 
    { 
    List<Node> list = new ArrayList<Node>(nodes.getLength()); 
    for (int i = 0, l = nodes.getLength(); i < l; i++) 
     list.add(nodes.item(i)); 
    return list; 
    } 
संबंधित मुद्दे

 संबंधित मुद्दे