如何从XML中读取属性,以及读取的XML文件有什么写法要求吗?
正如大家所了解的JAVA有两种方法加载java.util.Properties:
- load()
- loadFromXML()
load
有两个方法支持从文本文件中读取属性
- load(InputStream inStream)
- load(Reader reader)
name=dusk
age=25
从文本文件加载属性的代码如下:
/**
* 从文本文件中读取属性
*/
public static Properties load(){
Properties properties=new Properties();
InputStream is = PropertiesTest.class.getResourceAsStream("Properties.data");
try {
properties.load(is);
} catch (Exception e) {
e.printStackTrace();
}
return properties;
}
loadFromXML
支持从XML中读取属性。
新建一个XML文件Properties.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="name">dusk</entry>
<entry key="age">25</entry>
</properties>
从XML中加载属性的代码也很简单:
/**
* 从XML文件中读取属性
*/
public static Properties loadFromXML(){
Properties properties=new Properties();
InputStream is = PropertiesTest.class.getResourceAsStream("Properties.xml");
try {
properties.loadFromXML(is);
} catch (Exception e) {
e.printStackTrace();
}
return properties;
}
package com.dusk.properties;
import java.io.InputStream;
import java.util.Properties;
public class PropertiesTest {
public static void main(String[] args) {
Properties properties1=load();
System.out.println("----------文本文件---------");
System.out.println(properties1.getProperty("name"));
System.out.println(properties1.getProperty("age"));
Properties properties2=loadFromXML();
System.out.println("----------XML---------");
System.out.println(properties2.getProperty("name"));
System.out.println(properties2.getProperty("age"));
}
/**
* 从文本文件中读取属性
*/
public static Properties load(){
Properties properties=new Properties();
InputStream is = PropertiesTest.class.getResourceAsStream("Properties.data");
try {
properties.load(is);
} catch (Exception e) {
e.printStackTrace();
}
return properties;
}
/**
* 从XML文件中读取属性
*/
public static Properties loadFromXML(){
Properties properties=new Properties();
InputStream is = PropertiesTest.class.getResourceAsStream("Properties.xml");
try {
properties.loadFromXML(is);
} catch (Exception e) {
e.printStackTrace();
}
return properties;
}
}
运行结果:
项目结构如下图:
我们结束了吗?当然没这么low,因为文本的格式很简单明了,那么是不是所有的XML文件都支持吗?
当然不是了,下面我们关注一下XML文件必须符合的一些规范。
我们看loadFromXML源码:
我们看loadFromXML源码:
public synchronized void loadFromXML(InputStream in)
throws IOException, InvalidPropertiesFormatException
{
if (in == null)
throw new NullPointerException();
XMLUtils.load(this, in);
in.close();
}
发现它使用了XMLUtils.load
static void load(Properties props, InputStream in)
throws IOException, InvalidPropertiesFormatException
{
Document doc = null;
try {
doc = getLoadingDoc(in);
} catch (SAXException saxe) {
throw new InvalidPropertiesFormatException(saxe);
}
Element propertiesElement = doc.getDocumentElement();
String xmlVersion = propertiesElement.getAttribute("version");
if (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0)
throw new InvalidPropertiesFormatException(
"Exported Properties file format version " + xmlVersion +
" is not supported. This java installation can read" +
" versions " + EXTERNAL_XML_VERSION + " or older. You" +
" may need to install a newer version of JDK.");
importProperties(props, propertiesElement);
}
static Document getLoadingDoc(InputStream in)
throws SAXException, IOException
{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setIgnoringElementContentWhitespace(true);
dbf.setValidating(true);//开启了验证模式
dbf.setCoalescing(true);
dbf.setIgnoringComments(true);
try {
DocumentBuilder db = dbf.newDocumentBuilder();
db.setEntityResolver(new Resolver());
db.setErrorHandler(new EH());
InputSource is = new InputSource(in);
return db.parse(is);
} catch (ParserConfigurationException x) {
throw new Error(x);
}
}
static void importProperties(Properties props, Element propertiesElement) {
NodeList entries = propertiesElement.getChildNodes();
int numEntries = entries.getLength();
int start = numEntries > 0 &&
entries.item(0).getNodeName().equals("comment") ? 1 : 0;
for (int i=start; i<numEntries; i++) {
Element entry = (Element)entries.item(i);
if (entry.hasAttribute("key")) {
Node n = entry.getFirstChild();
String val = (n == null) ? "" : n.getNodeValue();
props.setProperty(entry.getAttribute("key"), val);
}
}
}
上面是解析XML的过程,其实XML的格式在DTD文件中已经定义:
<?xml version="1.0" encoding="UTF-8"?>
<!-- DTD for properties -->
<!ELEMENT properties ( comment?, entry* ) >
<!ATTLIST properties version CDATA #FIXED "1.0">
<!ELEMENT comment (#PCDATA) >
<!ELEMENT entry (#PCDATA) >
<!ATTLIST entry key CDATA #REQUIRED>
异常场景:java.lang.NoClassDefFoundError: org/w3c/dom/ElementTraversal
原因是缺少xml-apis.jar。