user3058450
user3058450

Reputation: 13

Java -Reverse XML attributes

The below code is to reverse the XML using DOM parser. Everything works fine but the problem is the attributes not reversing for ex: <element att1="foo" att2="bar" /> result should be <element att2="bar" att2="foo" />

How to reverse the XML attributes??

public static void main(String[] args) throws Exception {
    reverseChildElements();
}

public static void reverseChildElements() {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    Document doc = null;
    try {
        DocumentBuilder builder = factory.newDocumentBuilder();
        // Parse the input xml file
        doc = builder.parse("file.xml");
        Node firstChild = doc.getFirstChild();
        reverseChildNodes(firstChild);
        doc.replaceChild(firstChild, doc.getFirstChild());
        outputXml(doc);
    } catch (ParserConfigurationException | SAXException | IOException | TransformerException e) {
        e.printStackTrace();
    }
}

private static void reverseChildNodes(Node firstChild) {
    NodeList childNodes = firstChild.getChildNodes();
    Stack<Node> nodeStack = new Stack<Node>();
    // Put all the nodes into a Stack
    for (int i = 0; i < childNodes.getLength(); i++) {
        reverseChildNodes(childNodes.item(i));
        revereseAttributes(childNodes.item(i));
        nodeStack.push(childNodes.item(i));
    }
    // This is the last one which we entered
    while (!nodeStack.empty()) {
        firstChild.appendChild(firstChild.removeChild(nodeStack.pop()));
    }
}

private static void revereseAttributes(Node item) {
    if(item.hasAttributes() && item.getAttributes().getLength() > 1){
        NamedNodeMap attributesMap = item.getAttributes();
        List<Node> nodeStack = new ArrayList<Node>();
        for (int i = 0; i < attributesMap.getLength(); i++) {
            nodeStack.add(attributesMap.item(i));
        }
        for (Node node : nodeStack) {
            attributesMap.removeNamedItem(node.getNodeName());
            Attr atr = node.getOwnerDocument().createAttribute(node.getNodeName());
            atr.setValue(node.getNodeValue());
            attributesMap.setNamedItem(atr);
        }
    }

}

private static void outputXml(Document doc) throws TransformerException {
    TransformerFactory tf = TransformerFactory.newInstance();
    StringWriter writer = null;
        Transformer transformer = tf.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
                "yes");
        writer = new StringWriter();

        transformer.transform(new DOMSource(doc), new StreamResult(writer));
    System.out.println(writer.toString().replaceAll( "(?s)<!--.*?-->", "" ));
}

Upvotes: 0

Views: 748

Answers (1)

laune
laune

Reputation: 31290

XML attributes are, by definition, not ordered. Their appearance (within their containing element) in the XML document is completely at the mercy of the implementation of some XML writer.

No XML processor may base any logic of the order of the appearance of attributes.

That said, you should be content with being able to reverse the elements.

Upvotes: 3

Related Questions