`
terrencexu
  • 浏览: 122504 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Dom4J: Vistor模式替换XML中的正则表达式

阅读更多

今天介绍一个如何通过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 --

3
3
分享到:
评论

相关推荐

    vistor软件与tsm安装指南

    在我们的案例中,`vistor_2_1_1.tgz`是一个包含Vistor软件的压缩包,我们需要先将其解压并安装。 1. **Vistor软件的安装步骤**: - 解压文件:使用命令行工具(如Linux的tar命令)解压`vistor_2_1_1.tgz`。 - ...

    vistor.zip

    在“vistor.zip”这个压缩包中,我们可以推测包含了一些关于C++实现访问者模式的代码示例或教程。 访问者模式的主要优点在于其灵活性。当系统需要增加新的操作或者对现有对象结构进行操作时,我们可以通过定义新的...

    设计模式之访问者模式Vistor

    在实际应用中,访问者模式常用于处理具有相同结构但需要不同行为的元素集合,例如解析XML、编译器语法分析等场景。 **访问者模式的优点**: 1. **开放封闭原则**:增加新操作无需修改已有类的代码,符合开放封闭...

    vistor虚拟带库linux所需的rpm包

    【vistor虚拟带库在Linux环境下的安装与配置】 虚拟带库(Virtual Tape Library, VTL)是一种将硬盘存储模拟成磁带库的技术,它提供了与磁带库类似的备份和恢复功能,但速度更快,效率更高。Vistor是其中一种虚拟带...

    设计模式-行为模式

    设计模式是软件工程中的一种重要思想,它是一种在特定情境下解决常见问题的模板,可以被反复使用并推广到各种不同环境中。行为设计模式主要关注对象之间的交互和职责分配,帮助我们更好地理解和控制软件系统的动态...

    C#设计模式之Visitor

    **四、Visitor模式的应用场景** 1. **在对象结构中添加新的操作而不改变其结构**:当需要为已经存在的对象结构增加新功能时,使用访问者模式可以避免修改原有结构。 2. **对象结构中的元素具有多种类型**:访问者...

    C++设计模式课件24_Vistor_访问器.pdf

    ### C++设计模式之访问者(Vistor)模式解析 #### 概述 在软件开发领域,设计模式作为解决特定问题的最佳实践集合被广泛应用。其中,“访问者(Visitor)”模式是面向对象设计中的一种常用模式,它允许我们向一组...

    C++设计模式代码资源24_Vistor_访问器.zip

    总的来说,`C++设计模式代码资源24_Vistor_访问器.zip`提供了一个学习和实践C++访问者模式的实例,通过`Visitor1.cpp`和`Visitor2.cpp`的代码,我们可以深入理解如何在实际项目中运用这一模式,提高代码的灵活性和可...

    vistor虚拟带库安装程序

    在本案例中,"vistor虚拟带库安装程序"是专为Linux操作系统设计的一款软件,用于在Linux环境下搭建和管理虚拟带库。 首先,我们需要理解Linux系统的基础知识。Linux是一种开源的操作系统,广泛应用于服务器、数据...

    vistor安装指南.doc

    近期学习tsm备份,用vistor虚拟带库搭建实验环境。文档涵盖了整个环境的搭建过程,每一步很详细。

    访问者模式代码

    在实际应用中,访问者模式常用于处理具有复杂结构的对象集合,例如解析XML文档、编译器的语法分析等场景。通过访问者模式,我们可以很容易地添加新的操作,而无需更改现有的元素类。这有助于保持系统的灵活性和可...

    c#代码介绍23种设计模式-22访问者模式(附代码)

    1. 访问者模式的定义 访问者模式是封装一些施加于某种数据结构之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保存不变。 访问者模式适用于数据结构相对稳定的系统, 它把数据结构和作用于数据...

    Visitor模式Visitor模式

    Visitor 模式 Visitor 模式是一种行为型设计模式,它允许在不修改已有的类层次的情况下,增加新的操作或行为。这种模式可以使得开发者在不改变原有类层次的情况下,能够对对象进行不同的处理。 从给定的文件信息...

    C++设计模式之外观模式

    我们在使用visual studio进行编译C++代码时,你只是在菜单中选择了Build,然后visual studio就开始了一堆的编译工作;你应该知道,因为你的一个简单的Build动作,编译器在后台会进行语法分析,生成中间代码,生成...

    WINDOWS网络技术练习测试题参考答案.pdf

    这篇文档是关于Windows网络技术的练习测试题参考答案,主要涉及Windows Server 2008操作系统中的网络管理和安全设置。以下是根据题目内容整理出的相关知识点: 1. 隐藏共享文件夹的创建:在Windows Server 2008中,...

    mycat路由解析之Druid开发指南.docx

    这两种方式都可以方便地从SQL语句中提取表名、条件表达式、字段列表和值列表等信息,并且能够轻松地通过抽象语法树(AST)进行SQL改写。这对于实现动态路由逻辑特别有用。 #### 二、路由解析流程 ##### 总体流程 ...

Global site tag (gtag.js) - Google Analytics