我的目标是将每个dom元素(Node.ELEMENT_NODE
)包装在标有org.w3c.dom.Document
的当前<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);
}
}
答案 0 :(得分:11)
解决此类问题的最简单方法之一(就像任何XML转换一样)是使用XSLT 。
此XSLT转换:
<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>
应用于任何XML文档时,例如:
<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>
注意:作为练习,如何在Java代码中启动XSLT转换:)
答案 1 :(得分:6)
这会将Node.ELEMENT_NODE
中的每个org.w3c.dom.Document
换成<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);
}
}
如果要排除任何节点,只需在第一个for
循环中过滤掉它们。
答案 2 :(得分:4)
我想建议一个递归解决方案,它使用Node#replaceChild
方法用新标签替换节点:
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));
}
}
}
这是我的主要内容:
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);
}
我用这个xml测试了它:
<html>
<head>
<title>title</title>
</head>
<body>
<h1>title</h1>
<div>test</div>
</body>
</html>
我的主要打印出这个新的xml,这似乎是你想要的:
<?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>
希望这有帮助。
答案 3 :(得分:0)
作为非答案;-)我建议使用CSS ... something {background:red}
显然,这只有在你使用CSS时才有意义。
答案 4 :(得分:-1)
对于任何给定节点“节点”,文档“文档”来自此类应该有效。
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);