简体   繁体   中英

Add XML element in a child node if parent node meets a condition

I have a very simple question for you experts of XML. I want to add a new Element beside tuple_centre_name , with the same tag and different value, only if the username have a value I want, and another tuple_centre_name with the same value, here amministrazione , does NOT exist. I ask you because I find difficult to reach that element, check if another tuple_centre_name exists and then check the parent attribute .

I'm using DOM in JAVA. Thanks for helping me.

 <?xml version="1.0" encoding="UTF-8" standalone="no"?><accounts>
    <account>
        <username>fabio</username>
        <password>123456</password>
        <node>
            <tuple_centre_name>amministrazione</tuple_centre_name>
            <port>NP</port>
        </node>
    </account>

Example is shown here. Request: add a new tuple_centre_name named something else only if it does not already exist inside the element named fabio . Here, is the result I want:

 <?xml version="1.0" encoding="UTF-8" standalone="no"?><accounts>
    <account>
        <username>fabio</username>
        <password>123456</password>
        <node>
            <tuple_centre_name>amministrazione</tuple_centre_name>
            <tuple_centre_name>Something else</tuple_centre_name> //ok because `fabio` as username is fine for me
            <port>NP</port>     
        </node>
    </account>

You want XPath for this:

Document document = /* ... */;

final String username = "fabio";

XPathVariableResolver resolver = new XPathVariableResolver() {
    @Override
    public Object resolveVariable(QName varName) {
        return varName.getLocalPart().equals("user") ? username : null;
    }
};

Element newElement = document.createElement("tuple_centre_name");
newElement.appendChild(document.createTextNode("amministraione"));

XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setXPathVariableResolver(resolver);

Node tupleCentreNameNode = (Node) xpath.evaluate(
    "//account[username[text()=$user]]/node/tuple_centre_name",
    document,
    XPathConstants.NODE);

tupleCentreNameNode.getParentNode().insertBefore(newElement,
    tupleCentreNameNode.getNextSibling());

XPath usually looks like a directory path, which is where the account/node/tuple_centre_name part comes from. The two slashes at the start ( //account ) means "any account element, any number of levels deep in the document."

The account[username[text()=$user]] selector means "an account element which contains a username element whose text matches the XPath variable 'user'." XPath variables can be defined externally with an XPathVariableResolver. While it is possible to hard-code the username value in the XPath expression, you would need to escape various characters, including quotes and characters which are special in XML; passing the username as an XPath variable guarantees it will be correct.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM