Avatar billede npa Nybegynder
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
Avatar billede arne_v Ekspert
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 !
Avatar billede arne_v Ekspert
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;
  }
}
Avatar billede arne_v Ekspert
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;
          }
    }
}
Avatar billede arne_v Ekspert
24. oktober 2003 - 15:15 #4
Og ikke noget svar, da jeg strengt taget ikke svarer på det du spørger om.
Avatar billede =maddog= Nybegynder
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.....
Avatar billede arne_v Ekspert
03. november 2003 - 23:58 #6
Kommet videre ?
Avatar billede luffedrengen Nybegynder
25. maj 2004 - 22:58 #7
hvilket programmeringssprog bruger du?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester