这个问题的最高答案描述了一种在Java中实现有效的XSLT管道的技术:
[Java中有效的XSLT管道(或将结果重定向到源)http://codingdict.com/questions/155853
不幸的是,尽管Transformer似乎公开了用于设置XSLT参数的API,但这似乎没有任何效果。例如,我有以下代码:
变形金刚
import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.Templates; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.Transformer; import java.io.File; public class MyTransformer { public static void main(String[] args) throws javax.xml.transform.TransformerConfigurationException, javax.xml.transform.TransformerException{ SAXTransformerFactory stf = (SAXTransformerFactory)TransformerFactory.newInstance(); // These templates objects could be reused and obtained from elsewhere. Templates templates1 = stf.newTemplates(new StreamSource( new File("MyStylesheet1.xslt"))); Templates templates2 = stf.newTemplates(new StreamSource(new File("MyStylesheet2.xslt"))); TransformerHandler th1 = stf.newTransformerHandler(templates1); TransformerHandler th2 = stf.newTransformerHandler(templates2); th1.setResult(new SAXResult(th2)); th2.setResult(new StreamResult(System.out)); Transformer t = stf.newTransformer(); //SETTING PARAMETERS HERE t.setParameter("foo","this is from param 1"); t.setParameter("bar","this is from param 2"); t.transform(new StreamSource(new File("in.xml")), new SAXResult(th1)); // th1 feeds th2, which in turn feeds System.out. } }
MyStylesheet1.xslt
<?xml version="1.0"?> <stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:foo="urn:foo" version="1.0"> <output method="xml"/> <param name="foo"/> <template match="@*|node()"> <copy> <apply-templates select="@*|node()"/> </copy> </template> <template match="foo:my/foo:hello"> <copy> <foo:world> foo is : <value-of select="$foo"/> </foo:world> </copy> </template> </stylesheet>
MyStylesheet2.xslt
<?xml version="1.0"?> <stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:foo="urn:foo" version="1.0"> <output method="xml"/> <param name="bar"/> <template match="@*|node()"> <copy> <apply-templates select="@*|node()"/> </copy> </template> <template match="foo:my/foo:hello/foo:world"> <copy> <apply-templates select="@*|node()"/> <attribute name="attr"> <value-of select="$bar"/> </attribute> </copy> </template> </stylesheet>
in.xml
<my xmlns="urn:foo"> <hello/> </my>
这给了我以下输出:
<?xml version="1.0" encoding="UTF-8"?><my xmlns="urn:foo"> <hello><foo:world xmlns:foo="urn:foo">foo is : </foo:world></hello> </my>
如您所见,foo:world / @ attr为空,并且foo:world的文本内容为“ foo is:”。预期的行为是应该使用传递给setParameter方法的参数填充它们。
有没有一种方法可以使用此技术设置XSL转换参数。如果不是,那么谁能推荐一种替代方法来在Java中有效地转换样式表,从而也可以设置XSLT参数?
问题在于每个TransformerHandler都有一个与之关联的单独的Transformer。您的第二个模板有问题,但是由于这是一个示例,我想这没关系。你要:
//SETTING PARAMETERS HERE th1.getTransformer().setParameter("foo","this is from param 1"); th2.getTransformer().setParameter("bar","this is from param 2");
请注意,您也不需要创建第三个转换器,只需在th1.getTransformer()上启动转换链即可。