'How can I replace an attribute in xml with different value using Java?

I have an xml file:

<pickingOrderBeginEventMessage xmlns="http://www.xmlns.walmartstores.com/SuppyChain/FulfillmentManagement/GlobalIntegeratedFulfillment/">
    <MessageBody>
        <RoutingInfo>
            <SourceNode>
                <location>
                    <countryCode>US</countryCode>
                </location>
            </SourceNode>
        </RoutingInfo>
            <fulfillmentOrders>
                <fulfillmentOrder>
                    <orderNbr>784</orderNbr>
                </fulfillmentOrder>
            </fulfillmentOrders>
    </MessageBody>
</pickingOrderBeginEventMessage>

I want to change <orderNbr>784</orderNbr> to <orderNbr>784778474484747</orderNbr>

This is my method:
(Note that I am using dom4j.)

    public String replaceXML(String attribute,String oldValue, String newValue) throws SAXException, DocumentException, IOException, TransformerException {
        SAXReader xmlReader = new SAXReader();
        Document input = xmlReader.read("src/test/resources/xml/pick_begin.xml");
        xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
        xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        String expr = String.format("//*[contains(@%s, '%s')]", attribute, oldValue);
        XPath xpath = DocumentHelper.createXPath(expr);
        List<Node> nodes = xpath.selectNodes(input);
        for (int i = 0; i < nodes.size(); i++) {
            Element element = (Element) nodes.get(i);
            element.addAttribute(attribute, newValue);
        }
        TransformerFactory factory = TransformerFactory.newInstance();
        factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
        Transformer xformer = factory.newTransformer();
        xformer.setOutputProperty(OutputKeys.INDENT, "yes");
        Writer output = new StringWriter();
        xformer.transform(new DocumentSource(input), new StreamResult(output));
        return output.toString();
    }
}

Where String attribute is orderNbr, oldValue is 784 and newValue is 78455556767.

But with this method, the new value is not getting replaced. Where am I going wrong?



Solution 1:[1]

According to the XML file in your question, orderNbr is an element and not an attribute and its text value is 784. So you want to replace the text value with 78455556767.

Your code does not change the original XML because your XPath query string does not find anything.

Therefore you need to change two things in your code.

  1. The XPath query string.
  2. The method you call to change the XML.

The below code contains the two changes. The changed lines are indicated with the following comment at the end of the line.

// CHANGE HERE

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.List;

import javax.xml.XMLConstants;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.XPath;
import org.dom4j.io.DocumentSource;
import org.dom4j.io.SAXReader;
import org.xml.sax.SAXException;

public class ChngAttr {
    public static String replaceXML(String attribute,
                                    String oldValue,
                                    String newValue) throws DocumentException,
                                                            IOException,
                                                            SAXException,
                                                            TransformerException {
        SAXReader xmlReader = new SAXReader();
        Document input = xmlReader.read("pick_begin.xml");
        xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
        xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        String expr = String.format("//%s[text() = '%s']", attribute, oldValue); // CHANGE HERE
        XPath xpath = DocumentHelper.createXPath(expr);
        List<Node> nodes = xpath.selectNodes(input);
        for (int i = 0; i < nodes.size(); i++) {
            Element element = (Element) nodes.get(i);
            element.setText(newValue); // CHANGE HERE
        }
        TransformerFactory factory = TransformerFactory.newInstance();
        factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
        Transformer xformer = factory.newTransformer();
        xformer.setOutputProperty(OutputKeys.INDENT, "yes");
        Writer output = new StringWriter();
        xformer.transform(new DocumentSource(input), new StreamResult(output));
        return output.toString();
    }

    public static void main(String[] args) throws Exception {
        String result = replaceXML("orderNbr", "784", "78455556767");
        System.out.println(result);
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Abra