Omet navegació

4.2.1 Lectura

Anem a fer proves per poder comprovar el funcionament. Ens basem en el document cotxes.xml esmentat en la pregunta 4.1

Nota

Aneu amb compte, perquè en el document cotxes.xml davant de la primera etiqueta no pot haver ni retorn de carro ni un espai en blanc ni res

import java.io.FileNotFoundException;
import java.io.IOException;
 
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
 
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
 
 
public class MirarXML {
 
public static void main(String[] args) throws ParserConfigurationException, FileNotFoundException, IOException, SAXException {
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse("cotxes.xml");
System.out.println(doc.getNodeName());     // torna el nom del document. No és l'element arrel. Ens dirà #document
Element arrel = doc.getDocumentElement();  // apuntarà a l'element arrel
System.out.println(arrel.getNodeName());   // torna el nom de l'element. Ens dirà oferta
System.out.println(arrel.getNodeValue());  // torna el valor de l'element. Com és un element que conté altres elements, el valor és null
}
}

Tal i com està documentat, aquesta serà l'eixida:

#document
oferta
null

Anem a comprovar ara que el primer fill de oferta no és vehiculo sinó el retorn de carro. Els element vehiculo són el segon i el quart (índex 1 i 3).

import java.io.FileNotFoundException;
import java.io.IOException;
 
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
 
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
 
 
public class MirarXML2 {
 
    public static void main(String[] args) throws ParserConfigurationException, FileNotFoundException, IOException, SAXException {
        Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse("cotxes.xml");
        Element arrel = doc.getDocumentElement();  // apuntarà a l'element arrel
        NodeList fills = arrel.getChildNodes();
        System.out.println(fills.item(0).getNodeName());   // el primer fill és el retorn de carro.
        System.out.println(fills.item(1).getNodeName());   // el segon fill sí que és vehiculo
        System.out.println(fills.item(2).getNodeName());   // el tercer fill és el retorn de carro.
        System.out.println(fills.item(3).getNodeName());   // el quart fill sí que és vehiculo
        System.out.println(fills.item(4).getNodeName());   // el cinquè fill és el retorn de carro.
        System.out.println(fills.item(5).getNodeName());   // no existeix el sisè fill. Donarà error
        }
}

Observeu que en l'última sentència estem provocant un error:

#text
vehiculo
#text
vehiculo
#text
Exception in thread "main" java.lang.NullPointerException
    at Exemples.MirarXML2.main(MirarXML2.java:25)

Per tant, hem d'anar molt en compte amb els retorns de carro.

  • Per a poder esquivar els retorn de carro podríem mirar el tipus de cada node ( getNodeType() ), menysprear els els de tipus TEXT_NODE i considerar només els de tipus ELEMENT_NODE.
  • Però normalment l'accés que farem serà un poc més directe i més fàcil. Agafarem la llista de tots els element que tinguen un determinat nom amb getElementsByTagName(nom) . Evidentment en la llista no estaran els retorns de carro i així no tindrem problemes amb ells.

En el següent exemple recorrerem tots els element vehiculo. De cadascun agafarem el contingut dels elements marca i matricula. També agafem el contingut de l'atribut combustible de l'element motor:

public class MirarXmlCotxes {

    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {

        Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
                .parse(new FileInputStream("cotxes.xml"));
        Element arrel = (Element) doc.getChildNodes().item(0);
        NodeList llista = arrel.getElementsByTagName("vehiculo");

        for (int i = 0; i < llista.getLength(); i++) {
            Element el = (Element) llista.item(i);
            System.out.println(el.getNodeName() + " " + (i + 1));
            System.out.println("Marca: " + el.getElementsByTagName("marca").item(0).getChildNodes().item(0).getNodeValue());
            System.out.println("Matrícula: " + el.getElementsByTagName("matricula").item(0).getFirstChild().getNodeValue());
            System.out.println("Motor: " + el.getElementsByTagName("motor").item(0).getTextContent());
            System.out.println("Combustible: " + el.getElementsByTagName("motor").item(0).getAttributes().item(0).getNodeValue());
            Element m = (Element) el.getElementsByTagName("motor").item(0);
            System.out.println("Combustible: " + m.getAttribute("combustible"));
            System.out.println();
        }
        System.out.println(arrel.getTextContent());
    }
}

És molt important observar que quan tenim un element que ja té contingut, la informació no és accessible, sinó que hem d'anar al primer fill, que aquest ja és de tips TEXT_NODE, per agafar el seu valor.

En l'exemple:

  • Per a marca hem agafat de tota la llista de fills el primer, per traure el seu valor.
  • En matricula en compte d'agafar tota la llista de fills, només hem agafat el primer, i per tant és més ràpid.
  • I per a motor utilitzem el mètode getTextContent, que agafa el congingut de text de l'element i de tots els seus descendents. Com és un node de text ja sabem a priori que ens anirà bé, i per tant és la forma més ràpida.

L'atribut combustible de l'element motor l'hem tret de 2 maneres:

  • La primera agafant la llista d'atributs, i després el primer d'aquesta llista.
  • En la segona manera s'ha fet més elegant, anat a buscar la propietat en qüestió. Per això hem convertit el node en l'element m, per a poder utilitzar getAttribute.

Al final fem el getTextContent() sobre l'arrel per a comprovar que trau el seu contingut i el de tots els seus fills, per això apareix la informació duplicada

Aquest serà el resultat de l'exemple anterior:

vehiculo 1
Marca: ford
Matrícula: 1234AAA
Motor: duratorc 1.4
Combustible: gasolina
Combustible: gasolina

vehiculo 2
Marca: ford
Matrícula: 1235AAA
Motor: duratorc 2.0
Combustible: diesel
Combustible: diesel


 
    ford
    focus
    duratorc 1.4
    1234AAA
    12500
    12000
    10000
    pintura metalizada
    llantas
    11325.jpg
    11326.jpg
 
 
    ford
    focus
    duratorc 2.0
    1235AAA
    125000
    10000
    9000
    pintura metalizada
    spoiler trasero
    climatizador
    11327.jpg
    11328.jpg