24. oktober 2003 - 15:06
Der er
7 kommentarer
Hvordan tæller jeg noder i et DOM træ?
Når jeg parser et XML dokument med en DOM parser (jeg bruger xerces) har jeg et problem med at tælle mig frem til den rigtige node/attribut. Jeg bruger f.eks. kaldet: myDoc.getFirstChild().getChildNodes().item(1).getChildNodes().item(0).getNodeValue() Jeg ER klar over at textnoder og attributter skal tælles med, men hvad er de PRÆCISE regler DOM parseren bruger? Hilsen Niels
Annonceindlæg fra Computerworld
Vejen til succes er.. Kedelig!
Mød en af Nordens fremmeste eksperter i adfærdsdesign – Morten Münster, der bl.a. har skrevet ” Jytte fra marketing er desværre gået for i dag” – på Computerworld Cloud & AI Festival.
11. juli 2025
24. oktober 2003 - 15:12
#1
Tja - 1 node = 1 node vel... Det er vsært at sige noget mere præcist uden at vide hvor det er du tæller forkert. En ting ved jeg af egen erfaring - der er "ekstra" tekst noder ved linie skift og den slags. Men generelt råd: test på node værdi i.s.f. at bruge numre !
24. oktober 2003 - 15:13
#2
Eksempel hvor jeg tester på tagget i.s.f. at bruge numre: import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class DomTest4 { private final static String XML_FILE = "C:\\domtest.xml"; public static void main(String[] args) { writeXml(XML_FILE); readXml(XML_FILE); } private static void writeXml(String filename) { try { PrintWriter pw = new PrintWriter(new FileOutputStream(filename)); pw.println("<?xml version='1.0' standalone='yes'?>"); pw.println("<list>"); pw.println("<elm>"); pw.println("<key>1</key>"); pw.println("<val>a</val>"); pw.println("</elm>"); pw.println("<elm>"); pw.println("<key>2</key>"); pw.println("<val>bb</val>"); pw.println("</elm>"); pw.println("<elm>"); pw.println("<key>3</key>"); pw.println("<val>ccc</val>"); pw.println("</elm>"); pw.println("</list>"); pw.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } } private static void readXml(String filename) { try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(new File(filename)); NodeList elements = doc.getElementsByTagName("elm"); for (int i = 0; i < elements.getLength(); i++) { Node element = elements.item(i); NodeList subelements = element.getChildNodes(); for(int j = 0; j < subelements.getLength(); j++) { String tag = subelements.item(j).getNodeName(); if(tag.equals("key")) { System.out.println("key = " + subelements.item(j).getFirstChild().getNodeValue()); } if(tag.equals("val")) { System.out.println("val = " + subelements.item(j).getFirstChild().getNodeValue()); } } } } catch (FactoryConfigurationError e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return; } }
24. oktober 2003 - 15:15
#3
Muligvis kan du også have fornøjelse af en Walker. Eksempel: import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.traversal.DocumentTraversal; import org.w3c.dom.traversal.NodeFilter; import org.w3c.dom.traversal.TreeWalker; import org.xml.sax.SAXException; public class Walker { private final static String XML_FILE = "C:\\walktest.xml"; public static void main(String[] args) { writeXml(XML_FILE); readXml(XML_FILE); } private static void writeXml(String filename) { try { PrintWriter pw = new PrintWriter(new FileOutputStream(filename)); pw.println("<?xml version='1.0' standalone='yes'?>"); pw.println("<list>"); pw.println("<!-- first element -->"); pw.println("<element>element 1</element>"); pw.println("<!-- second element -->"); pw.println("<element>element 2</element>"); pw.println("</list>"); pw.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } } private static void readXml(String filename) { try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(new File(filename)); // oldfashioned way NodeList elements = doc.getElementsByTagName("element"); for (int i = 0; i < elements.getLength(); i++) { Node element = elements.item(i); System.out.println(element.getFirstChild().getNodeValue()); } System.out.println("----------"); // walk everything TreeWalker walk1 = ((DocumentTraversal)doc).createTreeWalker(doc.getDocumentElement(), NodeFilter.SHOW_ALL, null, false); Node n1; while((n1 = walk1.nextNode()) != null) { int type = n1.getNodeType(); String name = n1.getNodeName(); String value = n1.getNodeValue(); if (value != null) { value = value.replace('\n', ' '); } else { value = ""; } System.out.println(type + " " + name + " " + value); } System.out.println("----------"); // walk everything but comments TreeWalker walk2 = ((DocumentTraversal)doc).createTreeWalker(doc.getDocumentElement(), NodeFilter.SHOW_ALL & ~NodeFilter.SHOW_COMMENT, null, false); Node n2; while((n2 = walk2.nextNode()) != null) { int type = n2.getNodeType(); String name = n2.getNodeName(); String value = n2.getNodeValue(); if (value != null) { value = value.replace('\n', ' '); } else { value = ""; } System.out.println(type + " " + name + " " + value); } System.out.println("----------"); // walk all text that are child to element TreeWalker walk3 = ((DocumentTraversal)doc).createTreeWalker(doc.getDocumentElement(), NodeFilter.SHOW_TEXT, new Filter(), false); Node n3; while((n3 = walk3.nextNode()) != null) { int type = n3.getNodeType(); String name = n3.getNodeName(); String value = n3.getNodeValue(); if (value != null) { value = value.replace('\n', ' '); } else { value = ""; } System.out.println(type + " " + name + " " + value); } } catch (FactoryConfigurationError e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } class Filter implements NodeFilter { public short acceptNode(Node node) { if(node.getNodeType() == Node.TEXT_NODE && node.getParentNode().getNodeType() == Node.ELEMENT_NODE && node.getParentNode().getNodeName().equals("element")) { return NodeFilter.FILTER_ACCEPT; } else { return NodeFilter.FILTER_REJECT; } } }
24. oktober 2003 - 15:15
#4
Og ikke noget svar, da jeg strengt taget ikke svarer på det du spørger om.
24. oktober 2003 - 15:21
#5
Afhænger som sagt er parseren. Kender ikke Xerces, men nogle lader whitespace være en tom TextNode (nodeType==3). ex. <root> <tree> <leaf color="green" /> <leaf color="green" /> <cluster> birds in a nest </cluster> </tree> </root> kan eks. give _myroot=document.getElementsByTagName("root").item(0); _elm=_myroot.firstChild; alert(_elm.nodeType) // kan give 3 (TextNode) eller 1 (XMLElement). if (_elm.nodeType==3) { alert(_elm.nodeValue); // vil give "", da elm er en tom TextNode. } else { alert(_elm.tagName); // vil give "TREE" } Netscape's indbyggede XUL DomParser lader whitespace være TextNode's, mend Microsofts MSXML parser ignorerer whitespace. Håber jeg nærmer mig noget du kan bruge.....
03. november 2003 - 23:58
#6
Kommet videre ?
hvilket programmeringssprog bruger du?
Kurser inden for grundlæggende programmering