Java中使用XML字符串和XSLT字符串作为参数获取转换后的字符串,支持xsl:include、xsl:import
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; } }
本文首发于我的CSDN博客:https://blog.csdn.net/n_ithero/article/details/104006183