Java提高班 之操作Properties

如何从XML中读取属性,以及读取的XML文件有什么写法要求吗?

正如大家所了解的JAVA有两种方法加载java.util.Properties:

  • load()
  • loadFromXML()

load

有两个方法支持从文本文件中读取属性
  1. load(InputStream inStream)
  2. load(Reader reader)
新建一个文本文件Properties.data
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源码:
 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值