2011-12-15 25 views
11

tengo el siguiente archivo xml:¿Cómo se leen las propiedades del archivo xml con java?

<resources> 
    <resource id="res001"> 
     <property name="propA" value="A" /> 
     <property name="propB" value="B" /> 
    </resource> 
    <resource id="res002"> 
     <property name="propC" value="C" /> 
     <property name="propD" value="D" /> 
    </resource> 
    <resource id="res003"> 
     <property name="propE" value="E" /> 
     <property name="propF" value="F" /> 
    </resource> 
</resources> 

¿Cómo puedo hacer algo como esto con Java/XML:

Xml xml = new Xml("my.xml"); 
Resource res001 = xml.getResouceById("res003"); 
System.out.println("propF: " + res.getProperty("propF")); 

Así se imprime:

F 

He tratado de Apache commons-configurations XMLConfiguration con XPathExpressionEngine, pero simplemente no puedo hacer que funcione. He buscado en Google y encontró algunos ejemplos, pero tampoco iba a funcionar :( Busco una solución en la que no necesito a recorrer todos los elementos.

Saludos, Alex

+0

poco fuera de tema, pero ¿hay alguna razón en particular se almacenan las propiedades tan individual elementos y no como atributos? '' –

+0

No reconozco ese formato. ¿Qué es? –

+0

Emil, se siente más natural de esta manera. ¿cualquier otra sugerencia? – etxalpo

Respuesta

1

yo sólo lo haría utilizar JAXB para enlazar datos en conjunto de objetos que tienen una estructura similar a un documento XML

Algo así como:.

@XmlRootElement("resources") 
public class Resources { 
    public List<Resource> resource = new ArrayList<Resource>(); // important, can't be left null 
} 
public class Resource { 
    @XmlAttribute public String id; 
    public List<Property> property; 
} 
// and so on 

una posible Gotcha es con respecto a la lista de serialización, hay dos modos, envuelto y desenvuelto; en tu caso, quieres "desenvuelto". Javadocs para anotaciones debe mostrar una anotación para definir esto.

+0

Sí, pero primero crea un XSD y genera los beans.http: //jaxb.java.net/tutorial/ –

+0

No, en absoluto, si se necesitara XSD, preferiría tener un tratamiento de conducto. En su lugar, solo define POJO (con setters y getters, o campos públicos) y lo usa. No hay esquemas involucrados. – StaxMan

1

Hay muchas maneras. Una es hacer JDOM y xpath. Algo como esto (de este artículo: http://onjava.com/onjava/2005/01/12/xpath.html):

SAXBuilder saxBuilder = 
    new SAXBuilder("org.apache.xerces.parsers.SAXParser"); 
org.jdom.Document jdomDocument = 
    saxBuilder.build(new File("somefile"); 
org.jdom.Attribute levelNode = 
    (org.jdom.Attribute)(XPath.selectSingleNode(
     jdomDocument, 
     "/resources/resource[@id='res003']/property[@name='propF']/@value")); 
System.out.println(levelNode.getValue()); 

no prueba, pero debería funcionar. Para el tutorial de xpath, ver http://zvon.org/xxl/XPathTutorial/General/examples.html. Es el mejor y más rápido tutorial.

Tenga cuidado con el ciclo de vida de saxbuilder, si se llama con frecuencia.

0

I redommend la xstream.

Analiza el XML en el objeto con el mismo strutuct.

Sobre XStream

El su objeto será:

List<Resources> 

mientras Resources tienen los atributos, con setters y getters, id que es un objeto Property con attibutes name y value.

Esperanza esta ayuda

0

Si yo fuera usted, me gustaría utilizar una interfaz con sus métodos deseados (getProperty, Resource, etc.) y proporcionar una implementación de XPath.

10

Esto es trivial, suponiendo que esté dispuesto a volver a escribir su archivo de propiedades en el formato estándar de Java. Suponga que tiene la siguiente en un archivo llamado props.xml:

<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> 
<properties> 
    <comment>This is a comment</comment> 
    <entry key="propA">A</entry> 
    <entry key="propB">B</entry> 
    <entry key="propC">C</entry> 
    <entry key="propD">D</entry> 
    <entry key="propE">E</entry> 
    <entry key="propF">F</entry> 
</properties> 

Luego leer las propiedades del archivo de la siguiente manera:

java.util.Properties prop = new Properties(); 
prop.loadFromXML(new FileInputStream("props.xml")); 
System.out.println(prop.getProperty("propF")); 
0

Gracias por todas las respuestas y/o sugerencias! Probé algunas de las bibliotecas xml indicadas anteriormente y decidí ir con la biblioteca XML Simple. Encontré la clase de utilidad "Diccionario" especialmente útil, para evitar el bucle a través de todos los elementos. Elegante y simple :)

A continuación es cómo lo usé. Espero que pueda ayudar a alguien más ...

Saludos,

Alex

un ejemplo de trabajo (en Windows Vista):

ventana
package demo; 

import java.io.File; 

import org.simpleframework.xml.Serializer; 
import org.simpleframework.xml.core.Persister; 

public class Demo { 
    public static void main(String[] args) throws Exception { 
     File file = new File("c:\\temp\\resources.xml"); 
     Serializer serializer = new Persister(); 
     Resources resources = serializer.read(Resources.class, file); 

     Resource resource = resources.getResourceByName("res001"); 
     System.out.println(resource.getProperty("propA")); 
     System.out.println(resource.getProperty("propB")); 
    } 
} 

Consola:

A-001 
B-001 

Resources.java

package demo; 

import org.simpleframework.xml.ElementList; 
import org.simpleframework.xml.Root; 
import org.simpleframework.xml.util.Dictionary; 

@Root(name="resources") 
public class Resources { 
    @ElementList(entry = "resource", inline = true) 
    private Dictionary<Resource> resources = new Dictionary<Resource>(); 

    public Resources(@ElementList(entry = "resource", inline = true) Dictionary<Resource> resources) { 
     this.resources = resources; 
} 

    public Resource getResourceByName(String name){ 
     return resources.get(name); 
    } 
} 

Resource.java

package demo; 

import org.simpleframework.xml.Attribute; 
import org.simpleframework.xml.ElementList; 
import org.simpleframework.xml.util.Dictionary; 
import org.simpleframework.xml.util.Entry; 

public class Resource implements Entry{ 
    @Attribute(name = "name") private final String name; 
    @ElementList(inline=true, name="property") private Dictionary<Property> properties; 

    public Resource(
        @Attribute(name = "name") String name, 
        @ElementList(inline=true, name="property") Dictionary<Property> properties) { 
      this.name = name; 
      this.properties = properties; 
    } 

    public String getName() { 
     return name; 
    } 

    public String getProperty(String name) { 
     return properties.get(name).getValue(); 
    } 
} 

Property.java

package demo; 

import org.simpleframework.xml.Attribute; 
import org.simpleframework.xml.Root; 
import org.simpleframework.xml.util.Entry; 

@Root 
public class Property implements Entry{ 
    @Attribute(name="name") private String name; 
    @Attribute(name="value") private String value; 

    public Property(@Attribute(name="name") String name, @Attribute(name="value") String value) { 
     this.name = name; 
     this.value = value; 
    } 

    public String getName() { 
     return name; 
    } 

    public String getValue() { 
     return value; 
    } 
} 

resources.xml

<resources> 
    <resource name="res001"> 
     <property name="propA" value="A-001" /> 
     <property name="propB" value="B-001" /> 
    </resource> 
    <resource name="res002"> 
     <property name="propA" value="A-002" /> 
     <property name="propB" value="B-002" /> 
    </resource> 
    <resource name="res003"> 
     <property name="propA" value="A-003" /> 
     <property name="propB" value="B-003" /> 
    </resource> 
</resources> 
Cuestiones relacionadas