代码之家  ›  专栏  ›  技术社区  ›  Andrei Ciobanu

javadom-在一个元素之后插入另一个元素

  •  10
  • Andrei Ciobanu  · 技术社区  · 16 年前

    <?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>
    

    我想在 <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>
    

    我必须在函数中使用javadom来实现这一点。函数签名应如下所示:

     public void addActionDom(String name, String stepType, String stepName)
    

    哪里:

    • name 是预先存在的元素,之后将进行插入;
    • stepType
    • stepName 是新插入元素的name属性。

        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();
            }
        }
    }
    
    4 回复  |  直到 16 年前
        1
  •  23
  •   MatEngel f1sh    11 年前

    好吧,亚伦·迪古拉在速度上打败了我。我也得自己想办法。 我没用 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)方法,这对您来说非常简单。但不幸的是,没有。

        2
  •  4
  •   Aaron Digulla    16 年前

    这很简单,但是org.w3c.domapi有点。。。奇怪的是:

    Node next = cnl.item(i + 1);
    Node newChild = createChild();
    next.getParent().insertBefore(newChild, next);
    

    使用JDom,它更简单:

    Node newChild = createChild();
    cnl.getParent().addContent(i, newChild);
    
        3
  •  2
  •   Garett    16 年前

    elem.getParentNode().insertBefore(newElement, elem.getNextSibling());
    
        4
  •  2
  •   Lukas Eder    14 年前

    正如其他人所指出的,domapi对于这样简单的操作来说相当冗长。如果你用 jOOX

    // 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"));
    

    请注意API与 jQuery .