Reputation: 13
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
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