Visualizzazione dei risultati da 1 a 10 su 11

Discussione: Parsing file .gpx

Hybrid View

  1. #1
    Leggo che si hanno problemi con il DOM quando i file xml cominciano a pesare qualche mb. Fino ad ora i file gpx che ho visto a stento raggiungono i 100 kb. Punto a favore per il DOM. Allo stesso tempo mi pare di capire che tramite il SAX è piuttosto semplice scartare gli elementi che non servono e considerare solo quelli che servono. Tra l'altro a me serve solo estrapolare le informazioni e non modificarle.

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da Javino89 Visualizza il messaggio
    Leggo che si hanno problemi con il DOM quando i file xml cominciano a pesare qualche mb. Fino ad ora i file gpx che ho visto a stento raggiungono i 100 kb. Punto a favore per il DOM. Allo stesso tempo mi pare di capire che tramite il SAX è piuttosto semplice scartare gli elementi che non servono e considerare solo quelli che servono. Tra l'altro a me serve solo estrapolare le informazioni e non modificarle.
    Con SAX è facile scartare (o al contrario considerare) certi elementi, presi a sé stanti. Ma è più difficile gestire e tenere un "contesto" che fornisca informazioni tipo: a che livello di profondità si è arrivati, se un certo nodo è seguito da un altro nodo ben preciso, ecc... Perché sono cose da gestire espressamente "a mano" (SAX su questi aspetti non aiuta!).

    Con DOM hai semplicemente un ... albero e puoi "navigarci" dentro come vuoi, avanti, indietro, in profondità, ecc.... Ma appunto devi navigarci, cioè dovresti partire dal nodo radice, prendere la lista dei figli, dire es.: se un nodo figlio è <metadata> magari entri in un tuo metodo che scansiona e gestisce i suoi figli specifici, ecc....

    Altrimenti con DOM puoi usare XPath, che permette di "indirizzare" velocemente certi nodi usando una apposita espressione. A questo punto può essere utile (anzi è meglio..) fare un esempio. Anche perché nel tuo caso, nel documento .gpx c'è un inghippo un pochino rognoso: ovvero i namespace. Vedi che all'inizio c'è:

    <gpx xmlns="http://www.topografix.com/GPX/1/1" ....

    Vuol dire che c'è un namespace di "default" e tutti i tag gpx, metadata, link, trk, ecc... sono associati a questo namespace. E nella espressione XPath bisogna considerare i namespace: o direttamente (ma la espressione diventa mooolto complessa) o attraverso un prefisso, che però va "mappato" (con XPath di JAXP c'è la interfaccia NamespaceContext che non ha purtroppo implementazioni predefinite e bisogna farne una esplicita).

    Bene, dato il tuo file .gpx (per la mia prova ho solo chiuso i tag aperti, visto che non l'hai postato completo), ho scritto questo:

    codice:
    import java.util.*;
    import javax.xml.XMLConstants;
    import javax.xml.namespace.*;
    import javax.xml.parsers.*;
    import javax.xml.xpath.*;
    import org.w3c.dom.*;
    import org.xml.sax.*;
    
    public class LetturaGpx {
        public static void main(String[] args) {
            try {
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                dbf.setNamespaceAware(true);
                DocumentBuilder builder = dbf.newDocumentBuilder();
    
                Document document = builder.parse("prova.gpx");
    
                XPathFactory xpf = XPathFactory.newInstance();
                XPath xpath = xpf.newXPath();
                xpath.setNamespaceContext(new GpxNamespaceContext());
    
                Object result = xpath.evaluate("/gpx:gpx/gpx:trk/gpx:trkseg/gpx:trkpt/gpx:time/text()",
                        document, XPathConstants.NODESET);
    
                NodeList list = (NodeList) result;
    
                for (int i = 0; i < list.getLength(); i++) {
                    Node node = list.item(i);
    
                    System.out.println(node.getNodeValue());
                }
            } catch (Exception e) {
                System.err.println(e);
            }
        }
    }
    
    
    class GpxNamespaceContext implements NamespaceContext {
        public String getNamespaceURI(String prefix) {
            if (prefix == null) {
                throw new IllegalArgumentException("prefix cannot be null");
            } else if (prefix.equals("gpx")) {
                return "http://www.topografix.com/GPX/1/1";
            } else {
                return XMLConstants.NULL_NS_URI;
            }
        }
    
        public String getPrefix(String namespaceURI) {
            return null;   // getPrefix non serve in questo caso
        }
    
        public Iterator getPrefixes(String namespaceURI) {
            return null;   // getPrefixes non serve in questo caso
        }
    }
    L'output è:
    2007-06-20T13:00:00Z
    2007-06-20T13:00:07Z
    2007-06-20T13:00:32Z
    2007-06-20T13:01:01Z


    Ovvero: ho selezionato tutti i nodi di "testo" che sono quelli contenuti nei <time> sotto <trkpt>.
    Ultima modifica di andbin; 14-10-2013 a 22:42
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.