Java中带有参数的高效XSLT管道
这个问题的首要答案描述了一种在Java中实现高效XSLT管道的技术: 不幸的是,虽然Transformer似乎公开了用于设置XSLT参数的API,但这似乎没有任何效果。例如,我有以下代码: Transformer.javaJava中带有参数的高效XSLT管道,java,dom,sax,pipeline,xslt,Java,Dom,Sax,Pipeline,Xslt,这个问题的首要答案描述了一种在Java中实现高效XSLT管道的技术: 不幸的是,虽然Transformer似乎公开了用于设置XSLT参数的API,但这似乎没有任何效果。例如,我有以下代码: Transformer.java import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.Templates; import javax.xml.transform.sax.TransformerHan
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都有一个单独的与之相关的转换器。您的第二个模板有问题,但由于这是一个示例,我想这无关紧要。你想要:
//SETTING PARAMETERS HERE
th1.getTransformer().setParameter("foo","this is from param 1");
th2.getTransformer().setParameter("bar","this is from param 2");
请注意,您也不需要创建第三个转换器,只需在th1.getTransformer()上启动与上一个注释相关的转换链即可。
在th1.getTransformer()上调用transform(),结果再次指向th1是不正确的。它将被处理两次。
使用新的Transformer()如初始帖子中所示是正确的方法
t.transform(new StreamSource(new File("in.xml")), new SAXResult(th1));