How to read properties from xml file with java?

一世执手 提交于 2020-03-14 05:51:30

问题


I have the following xml file:

<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>

How can I do something like this with Java/Xml:

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

So it prints:

F

I have tried apache commons-configurations XMLConfiguration with XPathExpressionEngine, but I just can't make it work. I have googled and found some examples, but neither would work :( I'm looking for a solution where I don't need to loop through all the elements.

Regards, Alex


回答1:


This is trivial, assuming you're willing to re-write your properties file into the standard Java format. Assume you have the following in a file called 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>

Then read properties from the file like this:

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



回答2:


I would just use JAXB to bind data into set of objects that have structure similar to your XML document.

Something like:

@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

one possible gotcha is regarding List serialization; there are two modes, wrapped and unwrapped; in your case, you want "unwrapped". Javadocs for annotations should show annotation to define this.




回答3:


There are many ways. One is to do JDOM and xpath. Something like this (from this article: 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());

Did not test it, but should work. For xpath tutorial see http://zvon.org/xxl/XPathTutorial/General/examples.html . Its the best and fastest tutorial.

Take care about the saxbuilder lifecycle, if it is called often.




回答4:


I redommend the XStream.

It parse the XML in the object with same strutuct.

About XStream

The your object will be:

List<Resources>

while Resourceshave the attributes, with setters and getters, id that is an object Property with attibutes name and value.

Hope this help




回答5:


If I were you, I would use an interface with your desired methods (getProperty, Resource, etc) and provide an XPath implementation.




回答6:


Thanks for all the answers/suggestions! I tried some of the xml libraries given above and decided to go with the Simple XML library. I found the "Dictionary" utility class especially useful, to avoid looping through all the elements. Elegant and simple :)

Below is how I used it. I hope it can help someone else...

Regards,

Alex

A working example (on 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"));
    }
}

Console window:

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>



回答7:


There are several parsers you can use. For me these parsers worked fine:

  • Soup
  • SimpleXMLParser


来源:https://stackoverflow.com/questions/8528052/how-to-read-properties-from-xml-file-with-java

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!