2011-12-15 3 views
11

У меня есть следующий XML-файл:Как читать свойства из xml-файла с помощью 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> 

Как я могу сделать что-то подобное с Java/Xml:

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

Так печатает:

F 

Я попытался апача commons-configurations XMLConfiguration с XPathExpressionEngine, но я просто не могу заставить его работать. Я гугл и нашел несколько примеров, но ни будет работать :( Я ищу решение, где мне не нужно перебрать все элементы.

С уважением, Alex

+0

Немного не по теме, но есть какая-либо конкретная причина вы храните свои свойства в качестве индивидуального элементы, а не как атрибуты? '' –

+0

Я не распознаю этот формат. Что это? –

+0

Эмиль, Он чувствует себя наиболее естественным таким образом. любые другие предложения? – etxalpo

ответ

1

Я бы просто использовать JAXB для связывания данных в набор объектов, которые имеют структуру, похожую на документ XML

что-то вроде:.

@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 

один возможный Гоча в отношении списка сериализации, есть два режима, завернутый и развернутый; в вашем случае вы хотите «распаковать». Javadocs для аннотаций должен показать аннотацию, чтобы определить это.

+0

Да, но сначала создайте XSD и сгенерируйте beans.http: //jaxb.java.net/tutorial/ –

+0

Нет, абсолютно нет - если бы XSD был нужен, я бы предпочел иметь корневой канал. Вместо этого вы просто определяете POJO (с сеттерами и геттерами или публичными полями) и используете это. Нет Схемы. – StaxMan

1

Существует много способов. Один из них - сделать JDOM и xpath. Нечто подобное (из этой статьи: 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()); 

не проверял, но должно работать. Для руководства по xpath см. http://zvon.org/xxl/XPathTutorial/General/examples.html. Это лучший и быстрый учебник.

Позаботьтесь о жизненном цикле saxbuilder, если его часто называют.

0

Существует несколько парсеров, которые вы можете использовать. Для меня эти парсеры прекрасно работали:

0

установлена ​​ОС в XStream.

Он анализирует XML в объекте с тем же strutuct.

О XStream

ваш объект будет:

List<Resources> 

в то время как Resources имеют атрибуты, с сеттеров и добытчиками, id, который является объектом Property с name и атрибуты объявления value.

Надеется, что это поможет

0

Если бы я тебя, я хотел бы использовать интерфейс с требуемыми методами (getProperty, Resource и т.д.) и обеспечить реализацию XPath.

10

Это тривиально, если вы хотите переписать файл свойств в стандартный формат Java. Предположим, у вас есть следующие в файле 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> 

Затем читать свойства из файла, как это:

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

Спасибо за ответы на все вопросы/предложения! Я попробовал некоторые из библиотек xml, приведенных выше, и решил пойти с библиотекой XML Simple. Я нашел полезный класс утилиты «Словарь», чтобы избежать перебора всех элементов. Элегантный и простой :)

Ниже, как я его использовал. Я надеюсь, что это может помочь кому-то еще ...

С уважением,

Alex

рабочий пример (на Windows Vista):

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

окно консоли:

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>