Java: how to wrap all elements with <sometag> in org.w3c.dom?
My goal is to wrap each dom ( Node.ELEMENT_NODE) element with the current org.w3c.dom.Documenttag <something style="background-color:red"></something>.
public static void main(String[] args){
org.w3c.dom.DOMDocument doc;
paintAllNodes(doc, 0);
}
public static void paintAllNodes(Node node, int level) {
// Process node
// If there are any children, visit each one
NodeList list = node.getChildNodes();
for (int i=0; i<list.getLength(); i++) {
// Get child node
Node childNode = list.item(i);
// Visit child node
paintAllNodes(childNode, level+1);
}
}
I would like to offer you a recursive solution using a method Node#replaceChildto replace node with a new tag:
public static void paintAllNodes(Node node) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element somethingElement = node.getOwnerDocument().createElement("something");
somethingElement.setAttribute("style", "background-color:red");
node.getParentNode().replaceChild(somethingElement, node);
somethingElement.appendChild(node);
NodeList nodeList = node.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
paintAllNodes(nodeList.item(i));
}
}
}
This is my main:
public static void main(String[] args) throws SAXException, IOException,
ParserConfigurationException, TransformerException {
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document document = docBuilder.parse(new File("document.xml"));
paintAllNodes(document.getDocumentElement());
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
}
I tested it using this xml:
<html>
<head>
<title>title</title>
</head>
<body>
<h1>title</h1>
<div>test</div>
</body>
</html>
My main printed this new xml, which seems to be what you need:
<?xml version="1.0" encoding="UTF-8"?><something style="background-color:red"><html>
<something style="background-color:red"><head>
<something style="background-color:red"><title>title</title></something>
</head></something>
<something style="background-color:red"><body>
<something style="background-color:red"><h1>title</h1></something>
<something style="background-color:red"><div>test</div></something>
</body></something>
</html></something>
Hope this helps.
One of the easiest ways to solve such problems (as for any XML conversion) is to use XSLT .
This is the XSLT transformation :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<something style="background-color:red">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</something>
</xsl:template>
</xsl:stylesheet>
when applied to any XML document, for example:
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
, :
<something style="background-color:red">
<nums>
<something style="background-color:red">
<num>01</num>
</something>
<something style="background-color:red">
<num>02</num>
</something>
<something style="background-color:red">
<num>03</num>
</something>
<something style="background-color:red">
<num>04</num>
</something>
<something style="background-color:red">
<num>05</num>
</something>
<something style="background-color:red">
<num>06</num>
</something>
<something style="background-color:red">
<num>07</num>
</something>
<something style="background-color:red">
<num>08</num>
</something>
<something style="background-color:red">
<num>09</num>
</something>
<something style="background-color:red">
<num>10</num>
</something>
</nums>
</something>
: , XSLT Java-:)
This will cover everyone Node.ELEMENT_NODEin the org.w3c.dom.Documenttag <something>:
public static void paintAllNodes(Document doc) {
// build list of Node.ELEMENT_NODE to process
List<Node> nodes = new ArrayList<Node>();
NodeList list = doc.getElementsByTagName("*");
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
nodes.add(node);
}
}
// iterate through each node and wrap with <something> tag
for (Node node : nodes) {
// remember the next sibling for inserting at end
Node nextSibling = node.getNextSibling();
// remember the parent and remove this node from it
Node parent = node.getParentNode();
parent.removeChild(node);
// create <something> element and attach node
Element element = doc.createElement("something");
NamedNodeMap attributes = element.getAttributes();
Attr attr = doc.createAttribute("style");
attr.setNodeValue("background-color:red");
attributes.setNamedItem(attr);
element.appendChild(node);
// insert new element where the node was
parent.insertBefore(element, nextSibling);
}
}
If you want to exclude any nodes, just filter them in the first loop for.
For any given node, 'node', and the document 'document' derived from something like this should work.
Node parent = node.getParent();
Node nextSibling = node.getNextSibling();
parent.removeChild(node);
Element something = document.createElement("something");
NamedNodeMap atts = something.getAttributes();
Attr att = document.createAttribute("style");
att.setNodeValue("background-color:red;");
atts.setNamedItem(att);
something.addChild(node);
parent.insertBefore(something, nextSibling);