2011-12-15 12 views
11

Mam następujący plik XML:Jak odczytać właściwości z pliku xml za pomocą 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> 

Jak można zrobić coś takiego z Java/XML:

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

Więc drukuje:

F 

Próbowałem apache commons-configurationations XMLConfiguration z XPathExpressionEngine, ale po prostu nie mogę go uruchomić. Mam google i znaleźć kilka przykładów, ale nie będzie działać :( szukam rozwiązania, gdzie nie trzeba pętli wszystkich elementów.

Pozdrowienia, Alex

+0

Lekko off topic, ale czy jest jakiś szczególny powód, dla którego przechowywać swoje właściwości jako samodzielny elementy, a nie jako atrybuty? '' –

+0

Nie rozpoznaję tego formatu. Co to jest? –

+0

Emil, To wydaje się najbardziej naturalne w ten sposób. jakieś inne sugestie? – etxalpo

Odpowiedz

1

ja po prostu użyć JAXB do wiązania danych do zbioru obiektów, które mają strukturę podobną do dokumentu XML

coś takiego:.

@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 

jeden możliwy haczyka dotyczy listy serializacji; istnieją dwa tryby, zapakowane i nieopakowane; w twoim przypadku chcesz "odwijać". Javadocs dla adnotacji powinien wyświetlać adnotacje, aby to zdefiniować.

+0

Tak, ale najpierw stwórz XSD i wygeneruj bean.http: //jaxb.java.net/tutorial/ –

+0

Nie, absolutnie nie - jeśli XSD był potrzebny, wolę mieć kanał korzeniowy. Zamiast tego wystarczy zdefiniować POJO (z ustawiaczami i pobierającymi lub polami publicznymi) i użyć tego. Brak schematów. – StaxMan

1

Istnieje wiele sposobów. Jedną z nich jest JDOM i xpath. Coś jak to (z tego artykułu: 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()); 

nie testowałem, ale powinno działać. Samouczek dotyczący xpath - patrz: http://zvon.org/xxl/XPathTutorial/General/examples.html. To najlepszy i najszybszy samouczek.

Dbaj o cykl życia saxbuildera, jeśli jest on często używany.

0

I redommend z XStream.

Parsuje XML w obiekcie za pomocą tego samego kroku.

O XStream

The to Twój obiekt będzie:

List<Resources> 

podczas Resources mieć atrybuty, z ustawiające i pochłaniacze, id że to obiekt Property z atrybuty reklamy name i value.

Nadzieja ta pomoc

0

If I were you, chciałbym użyć interfejsu ze swoimi pożądanych metod (getProperty, Resource, etc) i zapewnić implementację XPath.

10

To jest trywialne, zakładając, że chcesz ponownie zapisać plik właściwości w standardowym formacie Java. Zakładam, że masz następujące w pliku o nazwie 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> 

Następnie odczytać właściwości z pliku jak poniżej:

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

Dzięki za wszystkie odpowiedzi/sugestie! Próbowałem niektóre z bibliotek xml podanych powyżej i zdecydowałem się na bibliotekę XML Simple. Uważam, że klasa narzędziowa "Dictionary" jest szczególnie przydatna, aby uniknąć zapętlenia wszystkich elementów. Elegancki i prosty :)

Poniżej opisuję sposób użycia. Mam nadzieję, że to pomoże ktoś inny ...

Pozdrowienia,

Alex

przykład roboczych (Windows Vista):

okiennych
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")); 
    } 
} 

konsoli:

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> 
Powiązane problemy