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 FPT Software
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