2011年末就不做外包了,期间虽然更新过博客园,次数依然少的可怜。
农历新年前分享点实用代码到博客吧。
这次分享的是Java中使用XML字符串和XSLT字符串作为参数获取转换后的结果字符串。
分享的方法仅解决上述问题,对于XSLT字符串中可能存在的XSLT注入问题、大字符串的性能问题未做考虑。
关键代码如下:
package Test;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.net.URLDecoder;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.xml.sax.InputSource;
public class Test {
private static final Logger logger = LogManager.getLogger(Test.class);
private static final TransformerFactory tFactory = getTransformerFactory();
public static void main(String[] args) {
try {
String xmlStr="<Parameters>\r\n" +
" <columnId>C5CAB5D6-E8E8-4E90-8FE2-2CCDCB4FE562</columnId>\r\n" +
" <_>1579165992522</_>\r\n" +
"</Parameters>";
String xsltStr="<xsl:if test=\"//Parameters/columnId!=''\">" +
"columnId=<xsl:value-of select=\"//Parameters/columnId\"/>" +
"</xsl:if>";
String resultStr=invokeXmlstrAndXslstr(xmlStr, xsltStr);
System.out.println("xmlStr:");
System.out.println(xmlStr);
System.out.println("xsltStr:");
System.out.println(xsltStr);
System.out.println("resultStr:");
System.out.println(resultStr);
} catch (Exception e) {
e.printStackTrace();
}
}
public static String invokeXmlstrAndXslstr(String xmlString, String xslString) throws Exception {
String returnXMLString = "";
Transformer transformer;
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
PrintWriter printWriter;
StreamSource source;
StreamResult result;
// 补全为XSLT字符串 根据实际应用决定是否需要这部分补全字符串的代码
xslString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"
+ "<xsl:output method=\"text\" version=\"5.0\" encoding=\"UTF-8\" indent=\"yes\" />"
+ " <xsl:template match=\"/\">" + xslString + " </xsl:template>" + "</xsl:stylesheet>";
transformer = tFactory.newTransformer(new SAXSource(new InputSource(new StringReader(xslString))));
source = new StreamSource(new StringReader(xmlString));
bytes = new ByteArrayOutputStream();
printWriter = new PrintWriter(bytes);
result = new StreamResult(printWriter);// 存放中间结果
// 使用指定的样式表,转换XML文档
transformer.transform(source, result);
if (bytes != null) {
returnXMLString = bytes.toString();
}
return returnXMLString;
}
public static TransformerFactory getTransformerFactory() {
TransformerFactory tFactoryObj = TransformerFactory.newInstance();
tFactoryObj.setURIResolver(new URIResolver() {
public Source resolve(String href, String base) throws TransformerException {
StreamSource ss = null;
try {
ss = getXSL(href);
} catch (Exception e) {
try {
throw e;
} catch (Exception e1) {
logger.error("获取include的XSLT文件异常!异常信息:", e1);
}
}
return ss;
}
});
return tFactoryObj;
}
/**
* 指定XSLT内部include或import的XSLT文件的完整路劲 该方法需要根据项目情况调整指定路劲的规则
*
* @param href include或import标签中href属性的值
* @return include或import的XSLT文件的完整路劲
* @throws Exception
*/
public static StreamSource getXSL(String href) throws Exception {
StreamSource ss;
String pathVal = Test.class.getResource("/").toString().replace("file:/", "/").replace("/WEB-INF/classes/", "/")
+ href;
pathVal = pathVal.replaceAll("//", "/");
pathVal = URLDecoder.decode(pathVal, "utf-8");
File f = new File(pathVal);
if (f.exists()) {
ss = new StreamSource(new FileInputStream(f));
} else {
f = new File("src/main/resources/xslt/" + href);
if (f.exists()) {
ss = new StreamSource(new FileInputStream(f));
} else {
ss = new StreamSource(Test.class.getResource("/xslt/" + href).openStream());
}
}
return ss;
}
}