Java'da tüm DOM öğeleri arasında yineleme yapmanın en etkili yolu nedir?
Bunun gibi bir şey ama mevcut org.w3c.dom.Document
üzerindeki her bir DOM öğesi için?
for(Node childNode = node.getFirstChild(); childNode!=null;){
Node nextChild = childNode.getNextSibling();
// Do something with childNode, including move or delete...
childNode = nextChild;
}
Temel olarak tüm öğeler üzerinde yineleme yapmanın iki yolu vardır:
1. Özyineleme kullanmak (sanırım en yaygın yol):
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"));
doSomething(document.getDocumentElement());
}
public static void doSomething(Node node) {
// do something with the current node instead of System.out
System.out.println(node.getNodeName());
NodeList nodeList = node.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node currentNode = nodeList.item(i);
if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
//calls this method for all the children which is Element
doSomething(currentNode);
}
}
}
*2. Parametre olarak `ile
getElementsByTagName()` yöntemini kullanarak özyinelemeden** kaçınma:
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"));
NodeList nodeList = document.getElementsByTagName("*");
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
// do something with the current element
System.out.println(node.getNodeName());
}
}
}
Bence bu yolların ikisi de verimli.
Umarım bu yardımcı olur.
for (int i = 0; i < nodeList.getLength(); i++)
olarak değiştirin
for (int i = 0, len = nodeList.getLength(); i < len; i++)
daha verimli olmak için.
Javanna cevabının ikinci yolu, daha düz ve öngörülebilir bir bellek modeli kullanma eğiliminde olduğu için en iyisi olabilir.
Ben de yakın zamanda bu sorunla karşılaştım. İşte benim çözümüm. Özyinelemeden kaçınmak istedim, bu yüzden bir while döngüsü kullandım.
Listede rastgele yerlere yapılan ekleme ve çıkarmalar yüzünden,
Ben LinkedList
uygulamasını seçtim.
/* traverses tree starting with given node */
private static List<Node> traverse(Node n)
{
return traverse(Arrays.asList(n));
}
/* traverses tree starting with given nodes */
private static List<Node> traverse(List<Node> nodes)
{
List<Node> open = new LinkedList<Node>(nodes);
List<Node> visited = new LinkedList<Node>();
ListIterator<Node> it = open.listIterator();
while (it.hasNext() || it.hasPrevious())
{
Node unvisited;
if (it.hasNext())
unvisited = it.next();
else
unvisited = it.previous();
it.remove();
List<Node> children = getChildren(unvisited);
for (Node child : children)
it.add(child);
visited.add(unvisited);
}
return visited;
}
private static List<Node> getChildren(Node n)
{
List<Node> children = asList(n.getChildNodes());
Iterator<Node> it = children.iterator();
while (it.hasNext())
if (it.next().getNodeType() != Node.ELEMENT_NODE)
it.remove();
return children;
}
private static List<Node> asList(NodeList nodes)
{
List<Node> list = new ArrayList<Node>(nodes.getLength());
for (int i = 0, l = nodes.getLength(); i < l; i++)
list.add(nodes.item(i));
return list;
}