java读取xml配置⽂件(⼩结)
使⽤DOM解析XML⽂档时,需要读⼊整个XML⽂档,然后在内存中创建DOM树,⽣成DOM树上的每个节点对象。只有在整个DOM树创建完毕后,我们才能做其他的操作,即使我们只需要修改根元素节点的第⼆个⼦节点,仍然需要在进⾏这个⼩⼩的修改之间分析整个⽂档,在内存中构建⽂档树。当XML⽂档⽐较⼤时,构建DOM树将花费⼤量的时间和内存。
⼀种替代的技术就是使⽤SAX,SAX允许你在读取⽂档的时候,即对它进⾏处理,解析完毕处理也就完成了,不必等待整个⽂档被分析存储之后才进⾏操作。
三步过程
为了使⽤ XML ⽂件中的信息,必须解析⽂件以创建⼀个 Document 对象。
Document 对象是⼀个接⼝(??为了统⼀吗 ),因⽽不能直接将它实例化;⼀般情况下,应⽤程序会相应使⽤⼀个⼯⼚。准确的过程因实现⽽异,但是基本思想是相同的。(同样,Level 3 标准化了这个任务。)在这个例⼦ Java 环境中,解析⽂件是⼀个三步过程:
人民的名义2上映时间1.创建 DocumentBuilderFactory。 DocumentBuilderFactory 对象创建 DocumentBuilder。
2.创建 DocumentBuilder。 DocumentBuilder 执⾏实际的解析以创建 Document 对象。
3.解析⽂件以创建 Document 对象。
现在您可以开始构建应⽤程序了。
基本的应⽤程序
⾸先创建⼀个基本的应⽤程序,即⼀个名为 OrderProcessor 的类。
『『 『 『
第⼀步是⽣成⼀个DocumentBuilderFactory对象,newInstance()是静态⽅法,所以可以直接类名点调⽤。
第⼆步是⽤⼯⼚⽣成⼀个DocumentBuilder对象,但是newDocumentBuilder()是抽象⽅法,还没实现,在这⾥就可以调⽤了吗?还是像你以前说的,只要能产⽣⼀个抽象类的对象,那么这个抽象类的所以抽象⽅法就都已经实现了?是这样吗
newDocumentBuilder()抽象⽅法肯定会被⾮抽象⼦类实现,这就发⽣了多态,执⾏时调⽤⼦类的重写后的⽅法
public class DocumentBuilderFactoryImpl extends DocumentBuilderFactory {
......................
}
sun的newInstance()⽅法
public static DocumentBuilderFactory newInstance() {
try {
return (DocumentBuilderFactory) FactoryFinder.find(
/* The default property name according to the JAXP spec */
"l.parsers.DocumentBuilderFactory",
/* The fallback implementation class name */
"s.internal.jaxp.DocumentBuilderFactoryImpl");
} catch (FactoryFinder.ConfigurationError e) {
throw new Exception(),
}
}
它应该是⽤反射返回了⼀个DocumentBuilderFactoryImpl的实例,然后⽤DocumentBuilderFactory强转,也就是:wInstance()返回⼀个Object类型的DocumentBuilderFactory实例,下⾯的就不⽤说了吧!
l.parsers.DocumentBuilder;
l.parsers.DocumentBuilderFactory;
import java.io.File;
import org.w3c.dom.Document;
public class OrderProcessor {
public static void main (String args[]) {
奚梦瑶家境File docFile = new File("l");
Document doc = null;
try {
DocumentBuilderFactory dbf = wInstance();
DocumentBuilder db = wDocumentBuilder();
doc = db.parse(docFile);
} catch (Exception e) {
System.out.print("Problem parsing the file: "+e.getMessage());
}
}
}
⾸先,Java 代码导⼊必要的类,然后它创建 OrderProcessor 应⽤程序。本教程中的例⼦仅处理⼀个⽂件,因此为简洁起见,应⽤程序包含了对该⽂件的直接引⽤。
因此 Document 对象可以在以后使⽤,应⽤程序把它定义在 try-catch 块之外。
在 try-catch 块中,应⽤程序创建了 DocumentBuilderFactory,然后再使⽤它来创建 DocumentBuilder。 最后,DocumentBuilder 解析⽂件以创建 Document。
解析器设置
使⽤ DocumentBuilder 创建解析器的优点之⼀在于能够控制 DocumentBuilderFactory 创建的解析器上的各种设置。例如,可以设置解析器验证⽂档:
try {
DocumentBuilderFactory dbf = wInstance();
dbf.setValidating(true);
DocumentBuilder db = wDocumentBuilder();
doc = db.parse(docFile);
} catch (Exception e) {
...
员工福利申请报告Java 的 DOM Level 2 实现允许通过以下⽅法控制解析器的参数:
setCoalescing():决定解析器是否要将 CDATA 节点转换为⽂本,以及是否要和周围的⽂本节点合并(如果适⽤的话)。其默认值为false。
setExpandEntityReferences(): 确定是否要展开外部实体引⽤。如果为 true,外部数据将插⼊⽂档。其默认值为 true。(请参阅参考资料以了解关于使⽤外部实体的技巧。)
setIgnoringComments():确定是否要忽略⽂件中的注释。其默认值为 false。
setIgnoringElementContentWhitespace():确定是否要忽略元素内容中的空⽩(类似于浏览器对待 HT
ML 的⽅式)。其默认值为false。
setNamespaceAware():确定解析器是否要注意名称空间信息。其默认值为 false。
setValidating():默认情况下,解析器不验证⽂档。将这个参数设置为 true 可打开验证功能。
W3C DOM
⽂档对象模型(DOM)是与平台和语⾔⽆关的接⼝,允许程序和脚本动态地访问和更新⽂档的内容,结构和样式。⽂档可以进⼀步处理,处理的结果可以放回到所提供的页⾯中。
表3-1 ⽤于处理XML⽂档的DOM元素属性
属性名
描述
childNodes
返回当前元素所有⼦元素的数组
firstChild
返回当前元素的第⼀个下级⼦元素 lastChild
返回当前元素的最后⼀个⼦元素 nextSibling
返回紧跟在当前元素后⾯的元素 nodeValue
指定表⽰元素值的读/写属性
parentNode
返回元素的⽗节点
previousSibling
返回紧邻当前元素之前的元素
表3-2 ⽤于遍历XML⽂档的DOM元素⽅法 ⽅法名
描述
getElementById(id) (document)
获取有指定唯⼀ID属性值⽂档中的元素 getElementsByTagName(name)
返回当前元素中有指定标记名的⼦元素的数组
hasChildNodes()
返回⼀个布尔值,指⽰元素是否有⼦元素
getAttribute(name)
返回元素的属性值,属性由name指定
表3-3 动态创建内容时所⽤的W3C DOM属性和⽅法
属性/⽅法
描述
观刈麦翻译
⽂档对象上的createElement⽅法可以创建由tagName指定的元素。如果以串div作为⽅法参数,就会⽣成⼀个div元素 ateTextNode(text)
⽂档对象的createTextNode⽅法会创建⼀个包含静态⽂本的节点
<element>.appendChild(childNode)
appendChild⽅法将指定的节点增加到当前元素的⼦节点列表。例如,可以增加⼀个option元素,作为select元素的⼦节点。 <element>.getAttribute(name)
这些⽅法分别获得和设置元素中name属性的值
<element>.setAttribute(name,value)
<element>.insertBefore(newNode,targetNode)
这个⽅法将节点newNode作为当前元素的⼦节点插到targetNode元素前⾯
<element>.removeAttribute(name)
这个⽅法从元素中删除属性name
<element>.removeChild(childNode)
这个⽅法从元素中删除⼦childNode
<element>.replaceChild(newNode,oldNode)
这个⽅法将节点oldNode替换为节点newNode
<element>.hasChildNodes()
这个⽅法返回⼀个布尔值,指⽰元素是否有⼦元素
Java和XML是黄⾦组合,⽹上已经有很多⽂章介绍,XML作为电⼦商务中数据交换,已经有其不可替代的作⽤,但是在平时系统开发中,我们不⼀定都⽤到数据交换,是不是⽆法使⽤XML了?
当然不是,现在已经有⼀个新趋势,Java程序的配置⽂件都开始使⽤XML格式,以前是使⽤类似windows的INI格式。(Java中也有Propertiesy这样的类专门处理这样的属性配置⽂件)。使⽤XML作为Java的配置⽂件有很多好处,从Tomcat的安装配置⽂件和J2ee的配置⽂件中,我们已经看到XML的普遍应⽤,让我们也跟随流⾏趋势⽤XML武装起来。
现在关键是如何读取XML配置⽂件?有好⼏种XML解析器:主要有DOM和SAX ,这些区别⽹上⽂章介绍很多。
在apache的XML项⽬组中,⽬前有Xerces Xalan Cocoon⼏个开发XML相关技术的project.Tomcat本⾝使⽤的是 Sun 的 JAXP,⽽其XSL Taglib project中使⽤Xerces解析器。
好了,上⾯都是⽐较烦⼈的理论问题,还是赶快切⼊XML的配置⽂件的读取吧。
在我们的程序中,通常要有⼀些根据主机环境确定的变量。⽐如数据库访问⽤户名和密码,不同的主机可能设置不⼀样。只要更改XML配置⽂件,就可以正常运⾏。 localhost
sqlname
username
password
上⾯这个l配置⽂件⼀般是放在tomcat的WEB-INF/classes⽬录下。
我们编制⼀个Java程序直接读取,将dbhost dbuser dbpassword提取出来供其他程序访问数据库⽤。
⽬前使⽤SAX⽐较的多,与DOM主要区别是 SAX是⼀⾏⼀⾏读取XML⽂件进⾏分析,适合⽐较⼤⽂件,DOM是⼀次性读⼊内存,显然不能对付⼤⽂件.这⾥我们使⽤SAX解析,由于SAX解析器不断在发展,⽹上有不少⽂章是针对⽼版本的.如果你使⽤JDK1.4 ,可以参考使⽤SAX处理XML⽂档⼀⽂.这⾥的程序是根据其改进并且经过实践调试得来的.。
l.sax.Attributes;
l.sax.helpers.DefaultHandler;
l.sax.SAXException;
import java.util.Properties;
//使⽤DefaultHandler的好处 是 不必陈列出所有⽅法,
public class ConfigParser extends DefaultHandler {
定义⼀个Properties ⽤来存放 dbhost dbuser dbpassword的值
private Properties props;
private String currentSet;
private String currentName;
private StringBuffer currentValue = new StringBuffer();
读取配置文件失败//构建器初始化props
public ConfigParser() {
this.props = new Properties();
}
public Properties getProps() {
return this.props;
}
家长意见与建议简短//定义开始解析元素的⽅法. 这⾥是将 中的名称xxx提取出来.
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
currentValue.delete(0, currentValue.length());