今天介绍一个如何通过Dom4J的Visitor模式替换XML文件中正则表达式的方法,感兴趣的话可以看看。
Vistor模式不是本文关注的重点,感兴趣可以看一下本文:http://www.patterndepot.com/put/8/visitor.pdf
Dom4J提供了一个接收Vistor的接口,可以通过自定义Vistor实现类对XML文件中的正则表达式进行替换,原理很简单,就不在此赘述了,直接上例子吧。
首先是XML配置文件: deployment.xml
<deployment id="${deploy.id}">
<build>
<release>${build.release}</release>
<type>${build.type}</type>
<number>${build.number}</number>
</build>
<host>
<id>${deploy.host}</id>
<localdir>#{deploy.host:LocalHome}</localdir>
<user>#{deploy.host:User}</user>
<password>#{deploy.host:Password}</password>
</host>
</deployment>
然后是XMLVariableTransformer,这个类是我自定义的一个类,用来封装替换正则表示的一些方法。
package com.javaeye.terrencexu.dom4j;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.VisitorSupport;
import org.dom4j.io.SAXReader;
public class XMLVariableTransformer {
private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\$\\{([\\w\\d\\./_]+)}");
private static final Pattern HOST_VARIABLE_PATTERN = Pattern.compile("#\\{([\\w\\d\\./_]+):([\\w\\d\\./_]+)}");
private Properties config;
private Map<String, Properties> hostConfigs;
public XMLVariableTransformer(Properties config, Map<String, Properties> hostConfigs) {
this.config = config;
this.hostConfigs = hostConfigs;
}
public String transform(String xml) {
SAXReader reader = new SAXReader();
try {
Document doc = reader.read(new ByteArrayInputStream(xml.getBytes()));
doc.accept(new VariableVistor());
return doc.asXML();
} catch (DocumentException e) {
e.printStackTrace();
throw new RuntimeException("Unable to read xml data", e);
}
}
public String transform(File xml) {
SAXReader reader = new SAXReader();
try {
Document doc = reader.read(xml);
doc.accept(new VariableVistor());
return doc.asXML();
} catch (DocumentException e) {
e.printStackTrace();
throw new RuntimeException("Unable to read xml data", e);
}
}
private class VariableVistor extends VisitorSupport {
public void visit(Attribute attr) {
parseNode(attr);
}
public void visit(Element node) {
parseNode(node);
}
private void parseNode(Node node) {
String substitution = getSubstitution(node.getText());
if(substitution != null) {
node.setText(substitution);
}
}
private String getSubstitution(String expression) {
Matcher m = XMLVariableTransformer.VARIABLE_PATTERN.matcher(expression);
if(m.matches()) {
return config.getProperty(m.group(1));
}
m = XMLVariableTransformer.HOST_VARIABLE_PATTERN.matcher(expression);
if(m.matches()) {
String host = config.getProperty(m.group(1));
return hostConfigs.get(host).getProperty(m.group(2));
}
return null;
}
}
}
该类中的内嵌类VariableVisitor继承了接口Visitor的默认实现类VisitorSupport,通过该类可以在遍历deployment.xml的每个节点以及attribute的时候按规则替换正则表达式。
最后是一个测试
package com.javaeye.terrencexu.dom4j;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.io.FileUtils;
public class Test {
public static void main(String[] args) throws IOException {
Properties config = new Properties();
config.setProperty("deploy.id", "test");
config.setProperty("build.release", "release1");
config.setProperty("build.type", "type1");
config.setProperty("build.number", "latest");
config.setProperty("deploy.host", "localhost");
Map<String, Properties> hostConfigs = new HashMap<String, Properties>();
Properties hostConfig = new Properties();
hostConfig.setProperty("LocalHome", "c:\\install\\");
hostConfig.setProperty("User", "Administrator");
hostConfig.setProperty("Password", "abc123_");
hostConfigs.put("localhost", hostConfig);
File xmlFile = new File("C:\\eclipse\\workspace1\\Terrence-JavaStudy\\study-dom4j\\conf\\deployment.xml");
String xml = FileUtils.readFileToString(xmlFile);
XMLVariableTransformer tranformer = new XMLVariableTransformer(config, hostConfigs);
String deployment = tranformer.transform(xml);
System.out.println(deployment);
}
}
运行结果如下:
<?xml version="1.0" encoding="UTF-8"?>
<deployment id="test">
<build>
<release>release1</release>
<type>type1</type>
<number>latest</number>
</build>
<host>
<id>localhost</id>
<localdir>c:\install\</localdir>
<user>Administrator</user>
<password>abc123_</password>
</host>
</deployment>
-- Done --
本文介绍如何利用Dom4J和Visitor模式替换XML文件中的正则表达式,通过自定义类实现对特定变量的解析与替换,展示了一种在实际开发中灵活运用模式解决特定需求的实例。
589

被折叠的 条评论
为什么被折叠?



