目前我们的Java应用程序使用一个以制表符分隔的*.cfg文件中保存的值。我们需要修改这个应用程序,使其现在使用一个XML文件。
读取这个文件中的值,最好/最简单的库是什么?
当然,根据您的需求,有很多好的解决方案。如果只是配置问题,您可以查看Jakarta commons-configuration和commons-digester。
您始终可以使用获取文档的标准JDK方法:
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
[...]
File file = new File("some/path");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(file);
XML代码:
<?xml version="1.0"?>
<company>
<staff id="1001">
<firstname>yong</firstname>
<lastname>mook kim</lastname>
<nickname>mkyong</nickname>
<salary>100000</salary>
</staff>
<staff id="2001">
<firstname>low</firstname>
<lastname>yin fong</lastname>
<nickname>fong fong</nickname>
<salary>200000</salary>
</staff>
</company>
Java 代码:
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import java.io.File;
public class ReadXMLFile {
public static void main(String argv[]) {
try {
File fXmlFile = new File("/Users/mkyong/staff.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
NodeList nList = doc.getElementsByTagName("staff");
System.out.println("----------------------------");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
System.out.println("\nCurrent Element :" + nNode.getNodeName());
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
System.out.println("Staff id : "
+ eElement.getAttribute("id"));
System.out.println("First Name : "
+ eElement.getElementsByTagName("firstname")
.item(0).getTextContent());
System.out.println("Last Name : "
+ eElement.getElementsByTagName("lastname")
.item(0).getTextContent());
System.out.println("Nick Name : "
+ eElement.getElementsByTagName("nickname")
.item(0).getTextContent());
System.out.println("Salary : "
+ eElement.getElementsByTagName("salary")
.item(0).getTextContent());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出:
----------------
Root element :company
----------------------------
Current Element :staff
Staff id : 1001
First Name : yong
Last Name : mook kim
Nick Name : mkyong
Salary : 100000
Current Element :staff
Staff id : 2001
First Name : low
Last Name : yin fong
Nick Name : fong fong
Salary : 200000
我建议您阅读这篇文章:Normalization in DOM parsing with java - how does it work?
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
- myhousenu.xom.Document
对象的方法:”import nu.xom.Builder;
import nu.xom.Document;
import java.io.File;
[...]
File file = new File("some/path");
Document document = new Builder().build(file);
org.w3c.dom.Document
在“纯JDK”方法中也不是很复杂,因此这只是简单的一点。但是使用好的库的优势仅从这里开始!无论您使用XML做什么,当使用像XOM这样的库时,您经常会得到更简单的解决方案,并且需要维护自己的代码较少。例如,考虑this与this,或this与this,或包含XOM和W3C DOM示例的此帖子。(这篇答案是我对XOM的评估之一,它在我的寻找最佳Java XML库来替代dom4j的过程中是一个强有力的竞争者。)
你为什么选择使用XML配置文件?我以前做过XML配置,但它们经常变成更多的麻烦。
我想真正的问题是,在你的情况下,是否使用类似Preferences API这样的东西会更好。
使用Preferences API而不是自己编写XML解决方案的原因:
避免典型的XML丑陋(DocumentFactory等),以及避免第三方库提供XML后端
内置支持默认值(不需要特殊处理缺少/损坏/无效条目)
无需为XML存储对值进行清理(CDATA包装等)
支持存储状态保证(无需不断将XML写入磁盘)
可配置的存储后端(磁盘文件、LDAP等)
免费多线程访问所有首选项
JAXB 是易于使用的,且包含在Java 6 SE中。通过使用JAXB或其他XML数据绑定库,如Simple,您不必自己处理XML,大部分工作都由库完成。基本用法是向现有POJO添加注释。这些注释将用于为您的数据生成XML模式,并在从/向文件读取/写入数据时使用。
我只用过jdom,它非常容易上手。
这里提供文档和下载链接:http://www.jdom.org/
如果你有一个非常大的文档,最好不要把全部内容读入内存,而是使用SAX解析器,在遇到特定标签和属性时调用你的方法。你需要创建一个状态机来处理接收到的调用。
根据您的应用程序和cfg文件的范围,属性文件可能是最简单的选择。虽然它不像XML那样优雅,但肯定更容易。
使用{{link1:java.beans.XMLDecoder
}},自Java SE 1.4以来成为核心组件。
XMLDecoder input = new XMLDecoder(new FileInputStream("some/path.xml"));
MyConfig config = (MyConfig) input.readObject();
input.close();
手动编写配置文件非常简单,或者可以使用相应的XMLEncoder
设置一些内容以在运行时编写新对象。
@Root
public class Entry {
@Attribute
private String a
@Attribute
private int b;
@Element
private Date c;
public String getSomething() {
return a;
}
}
@Root
public class Configuration {
@ElementList(inline=true)
private List<Entry> entries;
public List<Entry> getEntries() {
return entries;
}
}
然后,您只需指定位置即可读取整个文件,它将解析并填充带注释的POJO。这将执行所有类型转换和验证。如果需要,还可以为持久性回调进行注释。可以像下面这样进行阅读。
Serializer serializer = new Persister();
Configuration configuraiton = serializer.read(Configuration.class, fileLocation);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
- myhouse