最近一项目中用到了 它, 在这里做个总结:
在服务器和客户端消息传递的过程中, 客户端给服务器端发送的消息最终都会与一个String字符串的形式被接收。当然服务器就是去把该String 的content 转换为对应的xml、并从中读取出数据、以作后续处理。 这里说的就是xml处理块:
--------------------------------------------------------------------------------------------------
xml 封转处理方法
/**
* This software is the proprietary information of CoolServlets, Inc.
* Use is subject to license terms.
*/
import java.io.*;
import java.util.*;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.*;
import org.jdom.xpath.XPath;
public class XMLProperties {
private Log log = LogFactory.getLog(XMLProperties.class);
private Document doc;
private File file;
private String value;
/**
* 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();
/**
*根据一个文件生成 xml doc 对象
*/
public XMLProperties(File file) throws Exception {
this.file = file;
try {
SAXBuilder builder = new SAXBuilder();
builder.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
builder.setFeature("http://xml.org/sax/features/validation", false);
doc = builder.build(file);
}
catch (Exception e) {
//System.err.println("Error creating XML parser in "
//+ "PropertyManager.java");
log.error("XMLProperties construct exception occured!", e);
throw e;
}
}
/**
*这个方法是根据一个输入流 创建一个xml doc 对象
**/
public XMLProperties(InputStream in) throws Exception {
try {
SAXBuilder builder = new SAXBuilder();
builder.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
builder.setFeature("http://xml.org/sax/features/validation", false);
doc = builder.build(in);
}
catch (Exception e) {
//System.err.println("Error creating XML parser in "
//+ "PropertyManager.java");
log.error("XMLProperties construct exception occured!", e);
throw e;
}
}
/**
* Returns the values of all property.
*
* @return like "a=b;c=d"
*/
public String getAllProperty(){
value = "";
Element element = doc.getRootElement();
Iterator iter = element.getChildren().iterator();
while(iter.hasNext()){
element = (Element)iter.next();
getChildProperty(element, "");
}
if(value.length()>1 && value.charAt(value.length()-1)==';'){
value = value.substring(0, value.length()-1);
}
return value.replaceAll("\\\\", "\\\\\\\\");
}
public void getChildProperty(Element root, String prefix){
if(root.getChildren().size()==0){
if(StringUtils.isEmpty(prefix)){
value += root.getName() + "=" + root.getValue() + ";";
}else{
value += prefix + "." + root.getName() + "=" + root.getValue() + ";";
}
return;
}
Iterator iter = root.getChildren().iterator();
while(iter.hasNext()){
Element element = (Element)iter.next();
if(StringUtils.isEmpty(prefix)){
getChildProperty(element, root.getName());
}else{
getChildProperty(element, prefix + "." + root.getName());
}
}
}
/**
* 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) {
if (propertyCache.containsKey(name)) {
return (String)propertyCache.get(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;
}
}
/**
* 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();
}
//
/**
* 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 getPropertyOfXPath(String name) {
if (propertyCache.containsKey(name)) {
return (String)propertyCache.get(name);
}
Element element = null;
try{
XPath xpath = XPath.newInstance(name);
// Search for this property by traversing down the XML heirarchy.
element = doc.getRootElement();
List list = xpath.selectNodes(element);
Iterator iter = list.iterator();
if(iter.hasNext()) {
element = (Element) iter.next();
}else{
return null;
}
}catch(Exception e){
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;
}
}
/**
* Returns the attribute value of the specified property.
*
* @param name the name of the property to get.
* @return the value of the specified property.
*/
public String getOtherPropertyOfXPath(String name, String attribute) {
if (propertyCache.containsKey(name)) {
return (String)propertyCache.get(name);
}
Element element = null;
try{
XPath xpath = XPath.newInstance(name);
// Search for this property by traversing down the XML heirarchy.
element = doc.getRootElement();
List list = xpath.selectNodes(element);
Iterator iter = list.iterator();
if(iter.hasNext()) {
element = (Element) iter.next();
}else{
return null;
}
}catch(Exception e){
return null;
}
// At this point, we found a matching property, so return its value.
// Empty strings are returned as null.
String value = element.getAttributeValue(attribute);
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;
}
}
/**
* 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 setPropertyOfXPath(String name, String value) {
// Set cache correctly with prop name and value.
propertyCache.put(name, value);
// Search for this property by traversing down the XML heirarchy.
Element element = null;
try{
XPath xpath = XPath.newInstance(name);
// Search for this property by traversing down the XML heirarchy.
element = doc.getRootElement();
List list = xpath.selectNodes(element);
Iterator iter = list.iterator();
if(iter.hasNext()) {
element = (Element) iter.next();
}else{
return;
}
}catch(Exception e){
return;
}
// Set the value of the property in this node.
element.setText(value);
// write the XML properties to disk
saveProperties();
}
public void setPropertysOfXPath(String name, String value) {
// Set cache correctly with prop name and value.
propertyCache.put(name, value);
// Search for this property by traversing down the XML heirarchy.
Element element = null;
try{
XPath xpath = XPath.newInstance(name);
// Search for this property by traversing down the XML heirarchy.
element = doc.getRootElement();
List list = xpath.selectNodes(element);
Iterator iter = list.iterator();
while(iter.hasNext()) {
element = (Element) iter.next();
// Set the value of the property in this node.
element.setText(value);
// write the XML properties to disk
saveProperties();
}
}catch(Exception e){
e.printStackTrace();
}
}
///
/**
* 将 http://127.0.0.1/gzrb/html/2008-03/21/content_2065.htm 中域名换掉
*/
public void changePropertysOfXPath(String name, String srcValue) {
try{
Element[] eles = getElementsOfXPath(name);
for(int j=0;j<eles.length;j++){
String text = eles[j].getText();
if(srcValue.substring(srcValue.length()-1).equalsIgnoreCase("/")){
srcValue = srcValue.substring(srcValue.length()-1);
}
eles[j].setText(srcValue+text.substring(text.substring(8).indexOf("/")+8));
saveProperties();
}
}catch(Exception e){
e.printStackTrace();
}
}
/**
* 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);
}
}
/**
* 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;
}
/**
* 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;
}
/**
* Returns the value of the specified property.
*
* @param name the name of the property to get.
* @return the value of the specified property.
*/
public Element[] getElementsOfXPath(String name) {
Element element = null;
try{
XPath xpath = XPath.newInstance(name);
// Search for this property by traversing down the XML heirarchy.
element = doc.getRootElement();
List list = xpath.selectNodes(element);
Element[] ret = new Element[list.size()];
for (int i = 0; i < list.size(); i++) {
element = (Element) list.get(i);
ret[i] = element;
}
return ret;
}catch(Exception e){
return null;
}
}
}
可以根据这个类, 把客户端传入的xml String content 装换成 xml document:
XMLProperties properties = new XMLProperties(new ByteArrayInputStream(str.toString().getBytes(ENCODE)));
然后你就可以随便去里面的数据了。。。。
来个最简单的例子:
可以使用 public String getAllProperty() 这个方法得到所有的xml 节点和内容
但是你想要得到某一个节点的属性的话, 就得先得到该节点 :用public Element[] getElementsOfXPath(String name)方法,然后再通过Element的方法 getAttribute("key") 来获取;
--------------------------------------------------------------------------------------------------------------------
而说到封装一个xml的话, 方式就很多了, 像什么dom4j, degister,etc