2011-09-10 66 views

Respuesta

116

Aquí está un ejemplo DOM rápida que muestra cómo leer y escribir un simple archivo XML con la DTD:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<!DOCTYPE roles SYSTEM "roles.dtd"> 
<roles> 
    <role1>User</role1> 
    <role2>Author</role2> 
    <role3>Admin</role3> 
    <role4/> 
</roles> 

y el DTD:

<?xml version="1.0" encoding="UTF-8"?> 
<!ELEMENT roles (role1,role2,role3,role4)> 
<!ELEMENT role1 (#PCDATA)> 
<!ELEMENT role2 (#PCDATA)> 
<!ELEMENT role3 (#PCDATA)> 
<!ELEMENT role4 (#PCDATA)> 

Primera importación siguientes:

import javax.xml.parsers.*; 
import javax.xml.transform.*; 
import javax.xml.transform.dom.*; 
import javax.xml.transform.stream.*; 
import org.xml.sax.*; 
import org.w3c.dom.*; 

Aquí hay algunas variables que necesitará:

Aquí es un lector (cadena XML es el nombre de su archivo XML):

public boolean readXML(String xml) { 
     rolev = new ArrayList<String>(); 
     Document dom; 
     // Make an instance of the DocumentBuilderFactory 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     try { 
      // use the factory to take an instance of the document builder 
      DocumentBuilder db = dbf.newDocumentBuilder(); 
      // parse using the builder to get the DOM mapping of the  
      // XML file 
      dom = db.parse(xml); 

      Element doc = dom.getDocumentElement(); 

      role1 = getTextValue(role1, doc, "role1"); 
      if (role1 != null) { 
       if (!role1.isEmpty()) 
        rolev.add(role1); 
      } 
      role2 = getTextValue(role2, doc, "role2"); 
      if (role2 != null) { 
       if (!role2.isEmpty()) 
        rolev.add(role2); 
      } 
      role3 = getTextValue(role3, doc, "role3"); 
      if (role3 != null) { 
       if (!role3.isEmpty()) 
        rolev.add(role3); 
      } 
      role4 = getTextValue(role4, doc, "role4"); 
      if (role4 != null) { 
       if (!role4.isEmpty()) 
        rolev.add(role4); 
      } 
      return true; 

     } catch (ParserConfigurationException pce) { 
      System.out.println(pce.getMessage()); 
     } catch (SAXException se) { 
      System.out.println(se.getMessage()); 
     } catch (IOException ioe) { 
      System.err.println(ioe.getMessage()); 
     } 

     return false; 
    } 

Y aquí un escritor:

public void saveToXML(String xml) { 
    Document dom; 
    Element e = null; 

    // instance of a DocumentBuilderFactory 
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    try { 
     // use factory to get an instance of document builder 
     DocumentBuilder db = dbf.newDocumentBuilder(); 
     // create instance of DOM 
     dom = db.newDocument(); 

     // create the root element 
     Element rootEle = dom.createElement("roles"); 

     // create data elements and place them under root 
     e = dom.createElement("role1"); 
     e.appendChild(dom.createTextNode(role1)); 
     rootEle.appendChild(e); 

     e = dom.createElement("role2"); 
     e.appendChild(dom.createTextNode(role2)); 
     rootEle.appendChild(e); 

     e = dom.createElement("role3"); 
     e.appendChild(dom.createTextNode(role3)); 
     rootEle.appendChild(e); 

     e = dom.createElement("role4"); 
     e.appendChild(dom.createTextNode(role4)); 
     rootEle.appendChild(e); 

     dom.appendChild(rootEle); 

     try { 
      Transformer tr = TransformerFactory.newInstance().newTransformer(); 
      tr.setOutputProperty(OutputKeys.INDENT, "yes"); 
      tr.setOutputProperty(OutputKeys.METHOD, "xml"); 
      tr.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 
      tr.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "roles.dtd"); 
      tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); 

      // send DOM to file 
      tr.transform(new DOMSource(dom), 
           new StreamResult(new FileOutputStream(xml))); 

     } catch (TransformerException te) { 
      System.out.println(te.getMessage()); 
     } catch (IOException ioe) { 
      System.out.println(ioe.getMessage()); 
     } 
    } catch (ParserConfigurationException pce) { 
     System.out.println("UsersXML: Error trying to instantiate DocumentBuilder " + pce); 
    } 
} 

getTextValue está aquí:

private String getTextValue(String def, Element doc, String tag) { 
    String value = def; 
    NodeList nl; 
    nl = doc.getElementsByTagName(tag); 
    if (nl.getLength() > 0 && nl.item(0).hasChildNodes()) { 
     value = nl.item(0).getFirstChild().getNodeValue(); 
    } 
    return value; 
} 

¡Agregue algunos accesos y mutadores y listo!

+5

es el archivo DTD se necesita para que esto funcione o podemos leer xml sin el dtd? si se necesita dtd, ¿podemos generar un dtd desde xml fácilmente en lugar de tipearlo todo nosotros mismos? –

+3

Puede dejar el archivo dtd. Asegúrese de eliminar también la referencia del archivo xml: . Puede encontrar aplicaciones gratuitas de generadores dtd o utilizar un servicio en línea. Generan un archivo dtd "suficientemente bueno" para comenzar. Por lo general, tendrás que modificarlo un poco. –

+1

Gracias por la respuesta. :) –

10

La respuesta anterior solo trata del analizador DOM (que normalmente lee el archivo completo en la memoria y lo analiza, lo que para un archivo grande es un problema), puede usar un analizador SAX que utiliza menos memoria y es más rápido (de todos modos eso depende de tu código).

El analizador SAX realiza una devolución de llamada de algunas funciones cuando encuentra un comienzo de elemento, fin de elemento, atributo, texto entre elementos, etc., de modo que puede analizar el documento y al mismo tiempo obtener lo que necesita.

un código de ejemplo:

http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/

8

XML escritura utilizando JAXB (Java Arquitectura para la vinculación XML):

http://www.mkyong.com/java/jaxb-hello-world-example/

package com.mkyong.core; 

import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Customer { 

    String name; 
    int age; 
    int id; 

    public String getName() { 
     return name; 
    } 

    @XmlElement 
    public void setName(String name) { 
     this.name = name; 
    } 

    public int getAge() { 
     return age; 
    } 

    @XmlElement 
    public void setAge(int age) { 
     this.age = age; 
    } 

    public int getId() { 
     return id; 
    } 

    @XmlAttribute 
    public void setId(int id) { 
     this.id = id; 
    } 

} 

package com.mkyong.core; 

import java.io.File; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBException; 
import javax.xml.bind.Marshaller; 

public class JAXBExample { 
    public static void main(String[] args) { 

     Customer customer = new Customer(); 
     customer.setId(100); 
     customer.setName("mkyong"); 
     customer.setAge(29); 

     try { 

     File file = new File("C:\\file.xml"); 
     JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class); 
     Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); 

     // output pretty printed 
     jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     jaxbMarshaller.marshal(customer, file); 
     jaxbMarshaller.marshal(customer, System.out); 

      } catch (JAXBException e) { 
     e.printStackTrace(); 
      } 

    } 
} 
3

Las respuestas sólo cubren DOM/SAX y una copiar y pegar la implementación de un ejemplo de JAXB.

Sin embargo, falta un área grande cuando usa XML. En muchos proyectos/programas, existe la necesidad de almacenar/recuperar algunas estructuras de datos básicas. Su programa ya tiene una clase para sus objetos de negocios agradables y brillantes/estructuras de datos, solo desea una forma cómoda de convertir estos datos a una estructura XML para que pueda hacer más magia en ella (almacenar, cargar, enviar, manipular con XSLT) .

Aquí es donde brilla XStream. Simplemente anote las clases que contienen sus datos, o si no desea cambiar esas clases, configure una instancia de XStream para ordenar (objects -> xml) o unmarshalling (xml -> objects).

Internamente XStream utiliza la reflexión, los métodos readObject y readResolve de la serialización de objetos Java estándar.

Tienes una buena y rápida tutorial here:

Para dar una breve visión general de cómo funciona, también proporcionan algunos ejemplos de código criterio del juez y unmarshalls una estructura de datos. El marshalling/unmarshalling ocurre todo en el método main, el resto es solo código para generar algunos objetos de prueba y rellenar algunos datos para ellos. Es muy simple configurar la instancia xStream y la clasificación/desasignación se realiza con una línea de código cada una.

import java.math.BigDecimal; 
import java.util.ArrayList; 
import java.util.List; 

import com.thoughtworks.xstream.XStream; 

public class XStreamIsGreat { 

    public static void main(String[] args) { 
    XStream xStream = new XStream(); 
    xStream.alias("good", Good.class); 
    xStream.alias("pRoDuCeR", Producer.class); 
    xStream.alias("customer", Customer.class); 

    Producer a = new Producer("Apple"); 
    Producer s = new Producer("Samsung"); 
    Customer c = new Customer("Someone").add(new Good("S4", 10, new BigDecimal(600), s)) 
     .add(new Good("S4 mini", 5, new BigDecimal(450), s)).add(new Good("I5S", 3, new BigDecimal(875), a)); 
    String xml = xStream.toXML(c); // objects -> xml 
    System.out.println("Marshalled:\n" + xml); 
    Customer unmarshalledCustomer = (Customer)xStream.fromXML(xml); // xml -> objects 
    } 

    static class Good { 
    Producer producer; 

    String name; 

    int quantity; 

    BigDecimal price; 

    Good(String name, int quantity, BigDecimal price, Producer p) { 
     this.producer = p; 
     this.name = name; 
     this.quantity = quantity; 
     this.price = price; 
    } 

    } 

    static class Producer { 
    String name; 

    public Producer(String name) { 
     this.name = name; 
    } 
    } 

    static class Customer { 
    String name; 

    public Customer(String name) { 
     this.name = name; 
    } 

    List<Good> stock = new ArrayList<Good>(); 

    Customer add(Good g) { 
     stock.add(g); 
     return this; 
    } 
    } 
} 
1

Ok, ya que tiene DOM, jaxb y xstream en la lista de respuestas, todavía hay una manera completamente diferente a leer y escribir XML: Data projection Puede desacoplar la estructura XML y la estructura de Java mediante el uso de una biblioteca que proporciona vistas de lectura y escritura a los Datos XML como interfaces Java. Desde el tutorials:

Dadas algunas mundo real XML:

<weatherdata> 
    <weather 
    ... 
    degreetype="F" 
    lat="50.5520210266113" lon="6.24060010910034" 
    searchlocation="Monschau, Stadt Aachen, NW, Germany" 
      ... > 
    <current ... skytext="Clear" temperature="46"/> 
    </weather> 
</weatherdata> 

Con proyección de datos se puede definir una interfaz de proyección:

public interface WeatherData { 

@XBRead("/weatherdata/weather/@searchlocation") 
String getLocation(); 

@XBRead("/weatherdata/weather/current/@temperature") 
int getTemperature(); 

@XBRead("/weatherdata/weather/@degreetype") 
String getDegreeType(); 

@XBRead("/weatherdata/weather/current/@skytext") 
String getSkytext(); 

/** 
* This would be our "sub projection". A structure grouping two attribute 
* values in one object. 
*/ 
interface Coordinates { 
    @XBRead("@lon") 
    double getLongitude(); 

    @XBRead("@lat") 
    double getLatitude(); 
} 

@XBRead("/weatherdata/weather") 
Coordinates getCoordinates(); 
} 

Y el uso de las instancias de esta interfaz al igual que POJOs:

private void printWeatherData(String location) throws IOException { 

final String BaseURL = "http://weather.service.msn.com/find.aspx?outputview=search&weasearchstr="; 

// We let the projector fetch the data for us 
WeatherData weatherData = new XBProjector().io().url(BaseURL + location).read(WeatherData.class); 

// Print some values 
System.out.println("The weather in " + weatherData.getLocation() + ":"); 
System.out.println(weatherData.getSkytext()); 
System.out.println("Temperature: " + weatherData.getTemperature() + "°" 
            + weatherData.getDegreeType()); 

// Access our sub projection 
Coordinates coordinates = weatherData.getCoordinates(); 
System.out.println("The place is located at " + coordinates.getLatitude() + "," 
               + coordinates.getLongitude()); 
} 

Esto funciona incluso para crear XML, las expresiones XPath se pueden escribir mesa.

0

El analizador SAX funciona de manera diferente con un analizador DOM, no carga ningún documento XML en la memoria ni crea ninguna representación de objetos del documento XML. En cambio, el analizador SAX usa la función de devolución de llamada (org.xml.sax.helpers.DefaultHandler) para informar a los clientes sobre la estructura del documento XML.

SAX Parser es más rápido y utiliza menos memoria que el analizador DOM. Consulte los siguientes métodos de devolución de llamada de SAX:

startDocument() y endDocument() - Método llamado al principio y al final de un documento XML. startElement() y endElement() - Método llamado al principio y al final de un elemento de documento. caracteres() - Método llamado con los contenidos de texto entre las etiquetas de inicio y fin de un elemento de documento XML. 1. Archivo XML Crea un archivo XML simple.

<?xml version="1.0"?> 
<company> 
    <staff> 
     <firstname>yong</firstname> 
     <lastname>mook kim</lastname> 
     <nickname>mkyong</nickname> 
     <salary>100000</salary> 
    </staff> 
    <staff> 
     <firstname>low</firstname> 
     <lastname>yin fong</lastname> 
     <nickname>fong fong</nickname> 
     <salary>200000</salary> 
    </staff> 
</company> 
  1. Java Archive analizador Uso SAX para analizar el archivo XML.

import javax.xml.parsers.SAXParser;

import javax.xml.parsers.SAXParserFactory; 

import org.xml.sax.Attributes; 

import org.xml.sax.SAXException; 

import org.xml.sax.helpers.DefaultHandler; 

public class ReadXMLFile { 

public static void main(String argv[]) { 

try { 

SAXParserFactory factory = SAXParserFactory.newInstance(); 
SAXParser saxParser = factory.newSAXParser(); 

DefaultHandler handler = new DefaultHandler() { 

boolean bfname = false; 
boolean blname = false; 
boolean bnname = false; 
boolean bsalary = false; 

public void startElement(String uri, String localName,String qName, 
      Attributes attributes) throws SAXException { 

    System.out.println("Start Element :" + qName); 

    if (qName.equalsIgnoreCase("FIRSTNAME")) { 
     bfname = true; 
    } 

    if (qName.equalsIgnoreCase("LASTNAME")) { 
     blname = true; 
    } 

    if (qName.equalsIgnoreCase("NICKNAME")) { 
     bnname = true; 
    } 

    if (qName.equalsIgnoreCase("SALARY")) { 
     bsalary = true; 
    } 

} 

public void endElement(String uri, String localName, 
    String qName) throws SAXException { 

    System.out.println("End Element :" + qName); 

} 

public void characters(char ch[], int start, int length) throws SAXException { 

    if (bfname) { 
     System.out.println("First Name : " + new String(ch, start, length)); 
     bfname = false; 
    } 

    if (blname) { 
     System.out.println("Last Name : " + new String(ch, start, length)); 
     blname = false; 
    } 

    if (bnname) { 
     System.out.println("Nick Name : " + new String(ch, start, length)); 
     bnname = false; 
    } 

    if (bsalary) { 
     System.out.println("Salary : " + new String(ch, start, length)); 
     bsalary = false; 
    } 

} 

}; 

    saxParser.parse("c:\\file.xml", handler); 

} catch (Exception e) { 
    e.printStackTrace(); 
} 


    } 

} 

Resultado

de inicio Elemento: empresa
inicio Elemento: personal
inicio Elemento: Nombre
Nombre: Yong
extremo del elemento: Nombre
inicio Elemento: Apellido
Apellido : mook kim
Elemento final: apellido
Inicio Elemento: apodo
Nombre Nick: mkyong
Fin Elemento: apodo
y así sucesivamente ...

Fuente (MyKong) - http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/

Cuestiones relacionadas