Java DOM – 一个接一个地插入一个元素
给出以下XML文件:
我想在某个预先存在的元素之后在添加一个新元素 。 例如,如果我想在
"Assign1"
之后添加节点,则新XML应该是这样的:
我必须在一个函数中使用Java DOM来做到这一点。 函数签名应该是这样的:
public void addActionDom(String name, String stepType, String stepName)
哪里:
-
name
是预先存在的元素,之后将插入; -
stepType
是插入的元素类型; -
stepName
是新插入元素的name属性。
目前,我缺乏JDOM或任何其他Java XML库的经验。 你能给出一个示例代码,或者指向一个教程,其中插入一个元素之后插入。
这是我迄今为止的代码:
public void addActionDom(String name, String stepType, String stepName) { File xmlFile = new File(path + "/resources/" + BPELFilename); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db; try { /* Load XML */ db = dbf.newDocumentBuilder(); Document doc = db.parse(xmlFile); doc.getDocumentElement().normalize(); /* Iterate throughout the type tags and delete */ for (String cTag : typeTags) { NodeList cnl = doc.getElementsByTagName(cTag); for (int i = 0; i < cnl.getLength(); ++i) { Node cnode = cnl.item(i); if (cnode.getNodeType() == Node.ELEMENT_NODE) { Element elem = (Element)cnode; // 'elem' Element after which the insertion should be made if (elem.getAttribute("name").equals(name)) { Element newElement = doc.createElement(stepType); // Element to be inserted newElement.setAttribute("name", stepName); // CODE HERE } } } } /* Save the editing */ Transformer transformer = TransformerFactory.newInstance().newTransformer(); StreamResult result = new StreamResult(new FileOutputStream(path + "/resources/" + BPELFilename)); DOMSource source = new DOMSource(doc); transformer.transform(source, result); } catch (Exception e) { /* ParserConfigurationException */ /* SAXException */ /* IOException */ /* TransformerConfigurationException */ /* TransformerException */ /* Exception */ e.printStackTrace(); } } }
好吧,Aaron Digulla在速度方面打败了我。 不得不自己搞清楚。 我没有使用cnl.item(i+1)
但是使用了nextSibling()
:
Element newElement = doc.createElement(stepType); // Element to be inserted newElement.setAttribute("name", stepName); elem.getParentNode().insertBefore(newElement, elem.getNextSibling());
您无法在指定的索引处插入节点。 唯一的节点插入方法是
appendChild(Node node) //appends the given child to the end of the list of children
和
insertBefore(Node new, Node child) //inserts "new" into the list, before the 'child' node.
如果有一个insertAfter(Node new,Node child)方法,这对你来说非常容易。 但不幸的是,没有。
这很简单,但org.w3c.dom API有点奇怪:
Node next = cnl.item(i + 1); Node newChild = createChild(); next.getParent().insertBefore(newChild, next);
使用JDom,它更简单:
Node newChild = createChild(); cnl.getParent().addContent(i, newChild);
这没有经过测试,但您应该可以:
elem.getParentNode().insertBefore(newElement, elem.getNextSibling());
正如其他人所指出的那样,DOM API对于这种简单的操作非常冗长。 如果您使用类似jOOX的东西来包装DOM API,您可以编写以下任何内容:
// Find the element using XPath, and insert XML text after it $(document).xpath("//sequence/assign[@name='Assign1']") .after(" "); // Find the element using jOOX API, and insert an object after it $(document).find("sequence") .find("assign") .filter(attr("name", "Assign1")) .after($("newtype").attr("name", "NewNode"));
请注意API如何类似于jQuery 。