//工具类
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import org.jdom.xpath.XPath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Provides the the ability to use simple XML property files. Each property is
* in the form X.Y.Z, which would map to an XML snippet of:
*
* <pre>
* <X>
* <Y>
* <Z>someValue</Z>
* </Y>
* </X>
* </pre>
*
* The XML file is passed in to the constructor and must be readable and
* writtable. Setting property values will automatically persist those value to
* disk.
*/
public class XMLProperties {
private static final Logger m_logger = LoggerFactory.getLogger(XMLProperties.class);
private File file;
private Document doc;
private Element root;
// private Element element;
/**
* Parsing the XML file every time we need a property is slow. Therefore, we
* use a Map to cache property values that are accessed more than once.
*/
private Map propertyCache = new HashMap();
/**
* Creates a new XMLProperties object.
*
* @param file
* the full path the file that properties should be read from and
* written to.
*/
public XMLProperties(String file) {
this.file = new File(file);
try {
SAXBuilder builder = new SAXBuilder();
// Strip formatting
DataUnformatFilter format = new DataUnformatFilter();
builder.setXMLFilter(format);
doc = builder.build(new File(file));
root = doc.getRootElement();
} catch (Exception e) {
m_logger.error("Error creating XML parser in "
+ "PropertyManager.java");
e.printStackTrace();
}
}
/**
* Returns the value of the specified property.
*
* @param name
* the name of the property to get.
* @return the value of the specified property.
*/
public String getProperty(String name) {
String[] propName = parsePropertyName(name);
// Search for this property by traversing down the XML heirarchy.
Element element = doc.getRootElement();
for (int i = 0; i < propName.length; i++) {
element = element.getChild(propName[i]);
if (element == null) {
// This node doesn't match this part of the property name which
// indicates this property doesn't exist so return null.
return null;
}
}
// At this point, we found a matching property, so return its value.
// Empty strings are returned as null.
String value = element.getText();
if ("".equals(value)) {
return null;
} else {
// Add to cache so that getting property next time is fast.
value = value.trim();
propertyCache.put(name, value);
return value;
}
}
/**
* Return all children property names of a parent property as a String
* array, or an empty array if the if there are no children. For example,
* given the properties <tt>X.Y.A</tt>, <tt>X.Y.B</tt>, and
* <tt>X.Y.C</tt>, then the child properties of <tt>X.Y</tt> are
* <tt>A</tt>, <tt>B</tt>, and <tt>C</tt>.
*
* @param parent
* the name of the parent property.
* @return all child property values for the given parent.
*/
public String[] getChildrenProperties(String parent) {
String[] propName = parsePropertyName(parent);
// Search for this property by traversing down the XML heirarchy.
Element element = doc.getRootElement();
for (int i = 0; i < propName.length; i++) {
element = element.getChild(propName[i]);
if (element == null) {
// This node doesn't match this part of the property name which
// indicates this property doesn't exist so return empty array.
return new String[] {};
}
}
// We found matching property, return names of children.
List children = element.getChildren();
int childCount = children.size();
String[] childrenNames = new String[childCount];
for (int i = 0; i < childCount; i++) {
childrenNames[i] = ((Element) children.get(i)).getName();
}
return childrenNames;
}
/**
* Sets the value of the specified property. If the property doesn't
* currently exist, it will be automatically created.
*
* @param name
* the name of the property to set.
* @param value
* the new value for the property.
*/
public void setProperty(String name, String value) {
// Set cache correctly with prop name and value.
propertyCache.put(name, value);
String[] propName = parsePropertyName(name);
// Search for this property by traversing down the XML heirarchy.
Element element = doc.getRootElement();
for (int i = 0; i < propName.length; i++) {
// If we don't find this part of the property in the XML heirarchy
// we add it as a new node
if (element.getChild(propName[i]) == null) {
element.addContent(new Element(propName[i]));
}
element = element.getChild(propName[i]);
}
// Set the value of the property in this node.
element.setText(value);
// write the XML properties to disk
saveProperties();
}
/**
* Deletes the specified property.
*
* @param name
* the property to delete.
*/
public void deleteProperty(String name) {
String[] propName = parsePropertyName(name);
// Search for this property by traversing down the XML heirarchy.
Element element = doc.getRootElement();
for (int i = 0; i < propName.length - 1; i++) {
element = element.getChild(propName[i]);
// Can't find the property so return.
if (element == null) {
return;
}
}
// Found the correct element to remove, so remove it...
element.removeChild(propName[propName.length - 1]);
// .. then write to disk.
saveProperties();
}
/**
* Saves the properties to disk as an XML document. A temporary file is used
* during the writing process for maximum safety.
*/
private synchronized void saveProperties() {
OutputStream out = null;
boolean error = false;
// Write data out to a temporary file first.
File tempFile = null;
try {
tempFile = new File(file.getParentFile(), file.getName() + ".tmp");
// Use JDOM's XMLOutputter to do the writing and formatting. The
// file should always come out pretty-printed.
XMLOutputter outputter = new XMLOutputter();
out = new BufferedOutputStream(new FileOutputStream(tempFile));
outputter.output(doc, out);
} catch (Exception e) {
e.printStackTrace();
// There were errors so abort replacing the old property file.
error = true;
} finally {
try {
out.close();
} catch (Exception e) {
e.printStackTrace();
error = true;
}
}
// No errors occured, so we should be safe in replacing the old
if (!error) {
// Delete the old file so we can replace it.
file.delete();
// Rename the temp file. The delete and rename won't be an
// automic operation, but we should be pretty safe in general.
// At the very least, the temp file should remain in some form.
tempFile.renameTo(file);
}
}
/**
* Returns an array representation of the given Jive property. Jive
* properties are always in the format "prop.name.is.this" which would be
* represented as an array of four Strings.
*
* @param name
* the name of the Jive property.
* @return an array representation of the given Jive property.
*/
private String[] parsePropertyName(String name) {
// Figure out the number of parts of the name (this becomes the size
// of the resulting array).
int size = 1;
for (int i = 0; i < name.length(); i++) {
if (name.charAt(i) == '.') {
size++;
}
}
String[] propName = new String[size];
// Use a StringTokenizer to tokenize the property name.
StringTokenizer tokenizer = new StringTokenizer(name, ".");
int i = 0;
while (tokenizer.hasMoreTokens()) {
propName[i] = tokenizer.nextToken();
i++;
}
return propName;
}
/**
* Return XML File Document Object
*
* @return Document
*/
public Document getDocument() {
return doc;
}
/**
* Return Document Root Element
*
* @return Element
*/
public Element getRootElement() {
return root;
}
/***************************************************************************
* XPATH基础
* XPATH遵循文档对象模型(DOM)的路径格式,基本语法由表达式构成。在计算表达式的值之后产生一个对象,这种对象有以下四种基本类型:节点集合、布尔型、数字型和字符串型。XPATH基本上和在文件系统中寻找文件类似,如果路径是以"/"开头的,就表明该路径表示的是一个绝对路径,这和在UNIX系统中关于文件路径的定义是一致的。以"//"开头
* 则表示在文档中的任意位置查找。
*
* 以样例XML文档(friends.xml)为例来了解XPATH: <?xml version="1.0" encoding="UTF-8"?>
* <friends comment="Friends List"> <friend number="1"> <name>zoof</name>
* <sex value="male" /> <phone>87654321</phone> </friend> <friend
* number="2"> <name>joe</name> <sex value="male" /> <phone>87654322</phone>
* </friend> <friend number="3"> <name>joe</name> <sex value="female" />
* <phone>87654323</phone> </friend> </friends>
*
* 在XML文档中使用位置路径表达式来查找信息,这些表达式有很多种组成方式。一般我们用得最多的恐怕是 节点元素
* 查找。XPATH中用正斜杠(/)来分隔子结点,返回所有与 模式相匹配的元素。下面以几个 表达式 的例子来说明一下返回结果:
* 表达式:/friends/friend 返回:根元素friends下所有的 friend 元素(或节点)。
*
* 表达式:/friends/* 返回:根元素friends下所有的元素(或节点)。(“*”相当于通配符,表示“所有”的)
*
* 表达式://friend 返回:任意元素(或节点)下的所有 friend 元素(或节点)。(注意:不仅仅是1中
* 根元素friends下面的friend元素,如果存在的话)
*
* 表达式:/friends/friend[@number='1'] 返回:根元素下元素名称为
* friend,number属性为'1'的全部元素(或节点)。(对于元素或节点的附加元素,比如属性,函数等都要用方括号"[]"扩起来,属性前面要加
* 上"@"号)
*
* 表达式:/friends/friend/phone[text()='87654321'] 返回:元素friends/friend下电话号码为
* 87654321 的全部元素。(text()是XPATH的函数,功能是取出当前节点的文本内容,即content。)
*
* 表达式://name/parent::* 返回:name元素的所有父元素(或节点)。(parent::* 表示这个元素的所有的父节点的集合)
*
* 上面的介绍对于我们一般的应用基本上够用了,如果你需要进一步的深入,请查看W3C发布的关于XAPH的官方资料。
*
*
* 现在我们开始使用XPATH结合JDOM来操作XML文件了。JDOM的关于XPATH的api主要有一个类:Xpath.java,在org.jdom.xpath这个包中。这个类中的核心方法主要是两个静态方法:selectNodes()和selectSingleNode()。
* 前者根据一个xpath语句返回一组节点:List;后者根据一个xpath语句返回符合条件的第一个节点:Object。 public static
* List selectNodes(Object arg1,String arg2) throws org.jdom.JDOMException;
* public static Object selectSingleNode(Object arg1,String arg2) throws
* org.jdom.JDOMException;
*
* 在使用XPATH之前,请先确定你的classpath路径里面有如下几个JAR包,如果没有,请从JDOM的发行包中lib目录下copy:
* saxpaht.jar jaxen-core.jar jaxen-jdom.jar
**************************************************************************/
/**
* 根据XPATH地址路径获得所有满足条件的对象
*
* @param xPath
*
* @return List
*/
public List selectNodes(String xPath) {
List list = new ArrayList();
list.clear();
try {
list = XPath.selectNodes(root, xPath);
} catch (JDOMException e) {
e.printStackTrace();
}
return list;
}
/**
* 根据XPATH地址路径获得所有满足条件的对象
*
* @param xPath
*
* @return Element
*/
public Element selectSingleNode(String xPath) {
Element element = null;
try {
element = (Element) XPath.selectSingleNode(root, xPath);
} catch (JDOMException e) {
e.printStackTrace();
}
return element;
}
/**
* 根据节点名称获得节点值
*
* @param element
* @param name
* @return String
*/
public String getText(Element element, String name) {
name = element.getText();
return name;
}
/**
* 根据属性名称获得属性值
*
* @param element
* @param name
* @return String
*/
public String getAttributeValue(Element element, String name) {
name = element.getAttributeValue(name);
return name;
}
public static void main(String[] args) {
//Logger m_logger = Logger.getLogger(XMLProperties.class);
XMLProperties pp = new XMLProperties(
"E:/Web/WEB-INF/classes/config.xml");
// m_logger.debug(pp.getProperty("socket.NetCutover.SendToWhere.IP"));
// m_logger.debug(""+pp.getRootElement().get);
}
}
//应用
/**
* 获取指点名称的值
*
* @param name
* 属性名称字符串
* @return 返回指点名称的值
*/
public static String getLipossProperty(String name) {
if (properties == null) {
loadProperties();
}
return properties.getProperty(name);
}
/**
* 载入XML配置文件到XMLProperties实例中
*/
private synchronized static void loadProperties() {
if (properties == null) {
if (G_ServerHome == null) {
G_ServerHome = LipossGlobals.getLipossHome();
}
m_logger.debug(G_ServerHome);
String path = G_ServerHome + File.separator + "WEB-INF"
+ File.separator + "classes" + File.separator
+ LIPOSS_CONFIG_FILENAME;
m_logger.debug(path);
properties = new XMLProperties(path);
}
}
相关推荐
在 Java 开发中,XML 配置文件的使用变得越来越普遍,许多项目都开始使用 XML 作为配置文件的格式,例如 Tomcat 的安装配置文件和 J2EE 的配置文件。使用 XML 作为配置文件有很多好处,例如可以轻松地更改配置项,而...
XML配置文件的处理使用`XMLConfiguration`类。同样,通过指定文件路径,可以创建配置实例并获取配置信息。 2. **写入XML配置文件** 添加、修改XML配置使用`setProperty()`方法,删除则使用`removeProperty()`。保存...
Java解析XML配置文件是开发过程中常见的一项任务,特别是在基于Java的框架中,如Spring,大量使用XML文件来存储配置信息。DOM4J是Java中一个非常流行且功能强大的XML处理库,它提供了丰富的API用于读取、写入、修改...
XML配置文件则需要使用`javax.xml.parsers.DocumentBuilderFactory`和`org.w3c.dom.Document`等类来解析。 3. **存储数据**:解析后的数据通常以键值对的形式存储,可以是HashMap或其他数据结构。这样,程序可以...
在Java编程中,加载配置文件是一项常见的任务,它允许我们动态地设置应用的参数和环境,而无需修改代码。配置文件通常以.properties或.xml格式存储,包含键值对或者结构化数据,使得程序可以根据不同环境或者用户...
1. **XML配置文件**: XML是一种结构化数据存储格式,常用于复杂的应用程序配置。在Java中,我们可以使用DOM(Document Object Model)、SAX(Simple API for XML)或StAX(Streaming API for XML)等解析器来读取...
Java操作XML文件是Java开发中常见的一项任务,特别是在处理配置、数据交换或存储结构化信息时。XML(Extensible Markup Language)是一种标记语言,它的结构清晰、可读性强,易于机器解析和生成。本篇文章将深入探讨...
### 在web.xml中引入其他XML配置文件的步骤 在Java Web开发中,`web.xml`作为Web应用程序的核心配置文件,负责定义应用级别的配置信息。为了提高代码的可维护性和复用性,有时需要将一部分配置内容提取到独立的XML...
然后,我们可以创建一个`BeanContainer`类,用于加载XML配置文件,解析bean定义,并根据这些定义实例化bean。 ```java public class BeanDefinition { private String id; private String className; // ...其他...
- 使用`ClassPathXmlApplicationContext`或`FileSystemXmlApplicationContext`加载XML配置文件。 - 通过`getBean`方法获取配置的bean实例。 - 示例代码: ```java ApplicationContext context = new ...
在Spring框架中,XML配置文件是核心组成部分,它定义了bean的实例化、依赖注入以及其他的框架设置。本文将深入探讨如何模拟Spring的XML配置文件注入,并通过SAXBuilder解析XML文件来实现这一过程。 首先,理解XML...
例如,`java.io.FileInputStream`可以用来打开文件,然后`java.util.Properties`类可以加载并解析配置文件。以下是一个简单的示例: ```java Properties props = new Properties(); FileInputStream fis = new ...
Java 读取 XML 文件是 Java 开发中常见的一项任务,XML(eXtensible Markup Language)作为一种可扩展标记语言,广泛用于数据交换、配置存储等领域。本教程将深入讲解如何在 Java 中处理 XML 文件,同时涉及 XML 的 ...
- **DOM解析:** DOM(Document Object Model)模型将XML文件视为一个树形结构,通过`DocumentBuilder`类加载XML文件,生成`Document`对象,然后可以遍历整个文档节点进行操作。 - **SAX解析:** SAX(Simple API ...
总之,虽然Spring Boot主要依赖Java配置,但通过合理的使用`@ImportResource`和理解配置加载机制,我们可以灵活地在项目中融入XML配置文件,实现与Spring Boot的无缝集成。这使得我们能够在享受Spring Boot带来的...
在Java中,XML的应用广泛,包括配置文件、数据交换、Web服务等。本书第三版的更新可能包含了最新的XML处理API和技术,如DOM4J、JDOM、StAX等,这些都是Java中处理XML的常用库。 1. **DOM解析**:DOM(Document ...
理解`@ImportResource`注解,它实际上是在Spring的`spring-context`模块中定义的,用于在Spring容器启动时加载XML配置文件。`ImportResource`内部实现了`BeanDefinitionReader`接口,该接口负责读取XML文件并将其...
本篇文章将深入探讨如何使用DOM(Document Object Model)和SAX(Simple API for XML)两种不同的技术来解析XML配置文件,从而建立数据库连接。 一、DOM技术连接 DOM是一种树形模型,它将整个XML文档加载到内存中,...
Ibaites 是一个基于 Java 的优秀持久层框架,它通过 XML 配置文件将 SQL 语句与 Java 代码分离,使得数据库操作变得更加简单且易于维护。在 Ibaitis 中,`sqlMapConfig.xml` 文件是其核心配置文件之一,用于设置 ...