मैं एक स्क्रिप्ट बना रहा हूं जिसे एक्सएमएल फाइलों को पैच करना है, जिसमें तत्वों की एक सूची को दूसरे के साथ बदलना शामिल है। निम्न फ़ंक्शन एक पैच (उसी नाम वाले तत्वों की संभावित रूप से रिक्त सूची को शामिल करना) को उसी नाम से तत्वों की मूल तत्व की सूची (संभवतः एक खाली सूची) पर लागू करता है। (यह पैचिंग तर्क का केवल एक छोटा सा हिस्सा है)।मैं अभी पाया गया एक बाल तत्व क्यों नहीं हटा सकता? NOT_FOUND_ERR
क्यों, जब मैं कोड चलाता हूं, तो क्या मुझे निम्न त्रुटि मिलती है?
org.w3c.dom.DOMException: NOT_FOUND_ERR: An attempt is made to reference a node in a context where it does not exist.
at com.sun.org.apache.xerces.internal.dom.ParentNode.internalRemoveChild(ParentNode.java:503)
at com.sun.org.apache.xerces.internal.dom.ParentNode.removeChild(ParentNode.java:484)
at CombineSweeps$PTReplaceNodeList.apply(CombineSweeps.java:514)
(लाइन 514 से नीचे चिह्नित किया गया है।) जहाँ तक मुझे यह समझ के रूप में, मैं सिर्फ सत्यापित किया है कि तत्व मौजूद है (क्योंकि NodeList लाइव है, अपनी पहली प्रविष्टि हमेशा अगले मैच या अशक्त हो जाएगा)। दिलचस्प बात यह है कि यह हमेशा एक समस्या नहीं है।
private static class PTReplaceNodeList extends PTBase {
private final String name;
private final String nextElement;
private final List<Node> childList;
...
int apply(Document document, Node parent, Node node_unused) {
NodeList nodes;
// A marker for where to insert our nodes.
// We make a guess using nextElement (if null, means at end).
Node refNode = null;
if (parent instanceof Document) { // root element
Document parDoc = (Document) parent;
nodes = parDoc.getElementsByTagName(name);
if (nextElement != null) {
refNode = parDoc.getElementsByTagName(nextElement).item(0);
}
} else {
Element parElt = (Element) parent;
nodes = parElt.getElementsByTagName(name);
if (nextElement != null) {
refNode = parElt.getElementsByTagName(nextElement).item(0);
}
}
while (true) {
// iterate through the list of nodes
Node node = nodes.item(0);
if (node == null) {
break;
}
// Reliable guess: insert before node following last in list
refNode = node.getNextSibling();
parent.removeChild(node); // line 514
}
for (Node child : childList) {
Node imported = document.importNode(child, true);
parent.insertBefore(imported, refNode);
}
return childList.size();
}
}
संपादित करें: मैं getElementsByTagName()
के लिए एक स्थानापन्न (स्वीकार किए जाते हैं जवाब देखें) के रूप में निम्नलिखित समारोह का इस्तेमाल किया।
/** Returns all direct children of node with name name.
*
* Note: not the same as getElementsByTagName(), which finds all descendants. */
static List<Node> getChildNodes(Node node, String name){
ArrayList<Node> r = new ArrayList<Node>();
NodeList children = node.getChildNodes();
int l = children.getLength();
for(int i = 0; i < l; ++i){
if(name.equals(children.item(i).getNodeName()))
r.add(children.item(i));
}
return r;
}
धन्यवाद कैसे तुम दोनों। क्या कोई गैर-पुनरावर्ती संस्करण है- 'getChildNodes()' और अपना स्वयं का खोज-नाम-नाम लागू करें? जितना अधिक मैं जावा की एक्सएमएल लाइब्रेरी के बारे में सीख रहा हूं, उतना ही कम मैं इसे ढूंढ रहा हूं जो मैं उम्मीद करता हूं। – dhardy
मुझे लगता है कि आपको अपनी खुद की खोज –
लागू करना होगा यह सबसे अच्छा समाधान प्रतीत होता है। मैंने अपने मामले में 'सूची' लौटने वाला एक फ़ंक्शन लागू किया है, क्योंकि मैं वास्तव में 'नोडलिस्ट' के "लाइव" व्यवहार को भी नहीं चाहता हूं (मेरे प्रश्न के अंत में जोड़ा गया है क्योंकि मैं यहां कोड ब्लॉक पोस्ट नहीं कर सकता)। –
dhardy