今天介绍一个如何通过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 --
分享到:
相关推荐
在我们的案例中,`vistor_2_1_1.tgz`是一个包含Vistor软件的压缩包,我们需要先将其解压并安装。 1. **Vistor软件的安装步骤**: - 解压文件:使用命令行工具(如Linux的tar命令)解压`vistor_2_1_1.tgz`。 - ...
在“vistor.zip”这个压缩包中,我们可以推测包含了一些关于C++实现访问者模式的代码示例或教程。 访问者模式的主要优点在于其灵活性。当系统需要增加新的操作或者对现有对象结构进行操作时,我们可以通过定义新的...
在实际应用中,访问者模式常用于处理具有相同结构但需要不同行为的元素集合,例如解析XML、编译器语法分析等场景。 **访问者模式的优点**: 1. **开放封闭原则**:增加新操作无需修改已有类的代码,符合开放封闭...
【vistor虚拟带库在Linux环境下的安装与配置】 虚拟带库(Virtual Tape Library, VTL)是一种将硬盘存储模拟成磁带库的技术,它提供了与磁带库类似的备份和恢复功能,但速度更快,效率更高。Vistor是其中一种虚拟带...
设计模式是软件工程中的一种重要思想,它是一种在特定情境下解决常见问题的模板,可以被反复使用并推广到各种不同环境中。行为设计模式主要关注对象之间的交互和职责分配,帮助我们更好地理解和控制软件系统的动态...
**四、Visitor模式的应用场景** 1. **在对象结构中添加新的操作而不改变其结构**:当需要为已经存在的对象结构增加新功能时,使用访问者模式可以避免修改原有结构。 2. **对象结构中的元素具有多种类型**:访问者...
### C++设计模式之访问者(Vistor)模式解析 #### 概述 在软件开发领域,设计模式作为解决特定问题的最佳实践集合被广泛应用。其中,“访问者(Visitor)”模式是面向对象设计中的一种常用模式,它允许我们向一组...
总的来说,`C++设计模式代码资源24_Vistor_访问器.zip`提供了一个学习和实践C++访问者模式的实例,通过`Visitor1.cpp`和`Visitor2.cpp`的代码,我们可以深入理解如何在实际项目中运用这一模式,提高代码的灵活性和可...
在本案例中,"vistor虚拟带库安装程序"是专为Linux操作系统设计的一款软件,用于在Linux环境下搭建和管理虚拟带库。 首先,我们需要理解Linux系统的基础知识。Linux是一种开源的操作系统,广泛应用于服务器、数据...
近期学习tsm备份,用vistor虚拟带库搭建实验环境。文档涵盖了整个环境的搭建过程,每一步很详细。
在实际应用中,访问者模式常用于处理具有复杂结构的对象集合,例如解析XML文档、编译器的语法分析等场景。通过访问者模式,我们可以很容易地添加新的操作,而无需更改现有的元素类。这有助于保持系统的灵活性和可...
1. 访问者模式的定义 访问者模式是封装一些施加于某种数据结构之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保存不变。 访问者模式适用于数据结构相对稳定的系统, 它把数据结构和作用于数据...
Visitor 模式 Visitor 模式是一种行为型设计模式,它允许在不修改已有的类层次的情况下,增加新的操作或行为。这种模式可以使得开发者在不改变原有类层次的情况下,能够对对象进行不同的处理。 从给定的文件信息...
我们在使用visual studio进行编译C++代码时,你只是在菜单中选择了Build,然后visual studio就开始了一堆的编译工作;你应该知道,因为你的一个简单的Build动作,编译器在后台会进行语法分析,生成中间代码,生成...
这篇文档是关于Windows网络技术的练习测试题参考答案,主要涉及Windows Server 2008操作系统中的网络管理和安全设置。以下是根据题目内容整理出的相关知识点: 1. 隐藏共享文件夹的创建:在Windows Server 2008中,...
这两种方式都可以方便地从SQL语句中提取表名、条件表达式、字段列表和值列表等信息,并且能够轻松地通过抽象语法树(AST)进行SQL改写。这对于实现动态路由逻辑特别有用。 #### 二、路由解析流程 ##### 总体流程 ...