我知道我可以将参数从Java传递到xsl变换,但是如何在变换完成后将变量/参数读回来?
例如,我有一个像这样的xml文档:
<author>
<name>Barry Bonds</name>
<books>
<book>Hitting Home Runs</book>
<book>Cheating at Baseball</book>
<book>Nobody Likes Cooperstown Anyway</book>
<books>
<author>
在单个转换中,我希望能够转换name元素并将其存储为变量,并转换book元素并将它们存储为第二个变量。然后我想在转换后从Java代码中访问这两个变量。
这可能吗?如果可行,它是如何完成的?
感谢Michael Kay的回答,我现在有了解决方案。对于遇到此问题的其他人来说,这是一个显示其工作原理的单元测试:
import net.sf.saxon.*;
import org.junit.Test;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.assertEquals;
public class SimpleTransform {
@Test
public void splitOutput() throws TransformerException, UnsupportedEncodingException {
final Map<String, StreamResult> results = new HashMap<String, StreamResult>();
results.put("test1", new StreamResult(new ByteArrayOutputStream()));
results.put("test2", new StreamResult(new ByteArrayOutputStream()));
results.put("test3", new StreamResult(new ByteArrayOutputStream()));
TransformerFactoryImpl factory = new TransformerFactoryImpl();
Source source = new StandardURIResolver(new Configuration()).resolve("transform.xslt", null);
Controller xsl = (Controller) factory.newTransformer(source);
xsl.setOutputURIResolver(new OutputURIResolver() {
@Override
public Result resolve(String s, String s1) throws TransformerException {
return results.get(s);
}
@Override
public void close(Result result) throws TransformerException {
}
});
Source xsd = (Source) Transform.loadDocuments("input.xml", false, null, false);
StreamResult standardResult = new StreamResult(new ByteArrayOutputStream());
xsl.transform(xsd, standardResult);
for (Map.Entry<String, StreamResult> stringStreamResultEntry : results.entrySet()) {
System.out.println(stringStreamResultEntry.getKey() + ": " + ((ByteArrayOutputStream)stringStreamResultEntry.getValue().getOutputStream()).toString("UTF-8"));
}
assertEquals("<html>\n <body>test1</body>\n</html>", ((ByteArrayOutputStream) results.get("test1").getOutputStream()).toString("UTF-8"));
assertEquals("<html>\n <body>test2</body>\n</html>", ((ByteArrayOutputStream) results.get("test2").getOutputStream()).toString("UTF-8"));
assertEquals("<html>\n <body>test3</body>\n</html>", ((ByteArrayOutputStream) results.get("test3").getOutputStream()).toString("UTF-8"));
}
}
答案 0 :(得分:2)
切换到XSLT 2.0(在您的情况下实际上意味着Saxon),并使用xsl:result-document指令生成每个输出。您可以通过向Saxon注册一个OutputURIResolver将结果文档传送回Java应用程序 - 这是一个简单的类,在创建每个结果文档时会通知它。