`
terrencexu
  • 浏览: 121584 次
  • 性别: 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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics