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 。