Java DOM - 一个接一个地插入一个元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3405055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java DOM - Inserting an element, after another
提问by Andrei Ciobanu
Given the following XML file:
给定以下 XML 文件:
<?xml version="1.0" encoding="UTF-8"?>
<process
name="TestSVG2"
xmlns="http://www.example.org"
targetNamespace="http://www.example.org"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<sequence>
<receive name="Receive1" createInstance="yes"/>
<assign name="Assign1"/>
<invoke name="Invoke1"/>
<assign name="Assign2"/>
<reply name="Reply1"/>
</sequence>
</process>
I want to add a new element inside the <sequence></sequence>
after a certain pre-existing element. For example if I want to add the node after "Assign1"
, the new XML should like this:
我想<sequence></sequence>
在某个预先存在的元素之后添加一个新元素。例如,如果我想在 之后添加节点"Assign1"
,新的 XML 应该是这样的:
<sequence>
<receive name="Receive1" createInstance="yes"/>
<assign name="Assign1"/>
<newtype name="NewNode"/>
<invoke name="Invoke1"/>
<assign name="Assign2"/>
<reply name="Reply1"/>
</sequence>
I have to do this by using Java DOM, in a function. The function signature should like this:
我必须通过在函数中使用 Java DOM 来做到这一点。函数签名应该是这样的:
public void addActionDom(String name, String stepType, String stepName)
Where:
在哪里:
name
is the pre-existing element, after which the insertion will be made;stepType
is the inserted element type;stepName
is the name attribute of the newly inserted element.
name
是预先存在的元素,之后将进行插入;stepType
是插入的元素类型;stepName
是新插入元素的名称属性。
Currently I am lacking experience with JDOM, or any other Java XML library. Can you please give a sample code, or point me to a tutorial where an insertion after a certain element is made.
目前我缺乏 JDOM 或任何其他 Java XML 库的经验。你能给出一个示例代码,或者给我一个教程,在某个元素之后插入。
This is the code I have until now:
这是我到现在为止的代码:
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();
}
}
}
采纳答案by f1sh
Ok, Aaron Digulla beat me regarding speed. Had to figure it out myself as well.
I didnt use cnl.item(i+1)
but nextSibling()
:
好的,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());
You cannot insert Nodes at a specified index. The only node-inserting methods are
您不能在指定的索引处插入节点。唯一的节点插入方法是
appendChild(Node node) //appends the given child to the end of the list of children
and
和
insertBefore(Node new, Node child) //inserts "new" into the list, before the 'child' node.
If there was a insertAfter(Node new, Node child) method, this would be very easy for you. But there isn't, unfortunately.
如果有一个 insertAfter(Node new, Node child) 方法,这对你来说会很容易。但不幸的是,没有。
回答by Aaron Digulla
It's simple but the org.w3c.dom API is a bit ... odd for this:
这很简单,但 org.w3c.dom API 有点……奇怪:
Node next = cnl.item(i + 1);
Node newChild = createChild();
next.getParent().insertBefore(newChild, next);
With JDom, it's more simple:
有了 JDom,就更简单了:
Node newChild = createChild();
cnl.getParent().addContent(i, newChild);
回答by Garett
This is not tested but you should be able to do:
这未经测试,但您应该能够:
elem.getParentNode().insertBefore(newElement, elem.getNextSibling());
回答by Lukas Eder
As others have pointed out, the DOM API is quite verbose for such simple operations. If you use something like jOOXto wrap the DOM API, you could write any of the following:
正如其他人指出的那样,DOM API 对于这种简单的操作来说非常冗长。如果您使用jOOX 之类的东西来包装 DOM API,您可以编写以下任何内容:
// Find the element using XPath, and insert XML text after it
$(document).xpath("//sequence/assign[@name='Assign1']")
.after("<newtype name=\"NewNode\"/>");
// 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"));
Note how the API resembles that of jQuery.
请注意 API 与jQuery 的相似之处。