我需要使用多个源进行XSLT转换以生成一个XML文件。
例如:我有一个要转换的XML消息、一个要进行转换的XSL文件和一个由XSL文件导入的文档片段。
如果我只使用一个documentFragment它工作。以下链接:
- how-to-merge-2-xml-streams-in-java-by-xslt
…StringURIResolver
工作得很好。但它只适用于一个文档片段注入(仅使用XSL上的一个document()
函数作为链接的示例)。以下链接的代码为例,我对其进行了一些更改,以支持多次注入:
public final class StringURIResolver implements URIResolver {
Map<String, String> documents = new HashMap<String, String>();
public StringURIResolver put(final String href, final String document) {
documents.put(href, document);
return this;
}
public StringURIResolver put(HashMap<String, String> parameterMap) {
// Make a set from Map.
Set<Entry<String, String>> mapSet = parameterMap.entrySet();
// Get the Map Iterator
Iterator<Entry<String, String>> i = mapSet.iterator();
while (i.hasNext()) {
Map.Entry<String, String> mappedValue = (Map.Entry<String, String>) i.next();
documents.put(mappedValue.getKey().toString(), mappedValue.getValue().toString());
}
return this;
}
public Source resolve(final String href, final String base) throws TransformerException {
System.out.println("RESOLVE WAS CALLED");
final String s = documents.get(href);
if (s != null) {
return new StreamSource(new StringReader(s));
}
return null;
}
}
我这里的问题很简单,StringResolver.resolve()
方法只调用一次我的整个XSL文件。
XSL的代码片段如下:
<xsl:variable name="Test.reply" select="document('Test.reply')" />
<xsl:variable name="Test.reply2" select="document('Test.reply2')" />
<xsl:variable name="Test.reply3" select="document('Test.reply3')" />
在我的JUnit测试中,当转换发生时,只有一次调用解析,消息"resolve WAS called"被打印一次,并且不使用第二和第三个片段。
我使用下面的代码使用一个Saxon9 Transformer:
private static TransformerFactory getConfiguredTransformerFactory() {
// Used to define the Default XML Transformer to SAXON 9.
System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
TransformerFactory transformerFactory = new TransformerFactoryImpl();
return transformerFactory;
}
请如果有任何解决方案,使URIResolver.resolve()
被调用的每个document()
函数的XSL或一个新的方法来合并多个字符串xml到一个用于转换,我将不胜感激。
您确定在样式表的某个地方使用了这三个变量吗?只要它们能被访问,它就能工作。(创建变量是不够的。)
例如,我在Java中包含了以下内容:StringURIResolver resolver = new StringURIResolver() {{
put("doc1", "<test1/>");
put("doc2", "<test2/>");
}};
在我的样式表中(仅使用$doc1
):
<xsl:variable name="doc1" select="document('doc1')" />
<xsl:variable name="doc2" select="document('doc2')" />
<xsl:value-of select="concat('c=', count($doc1/*))"/>
输出:RESOLVE WAS CALLED
c=1
但是,当我同时包含对两者的引用时:
<xsl:variable name="doc1" select="document('doc1')" />
<xsl:variable name="doc2" select="document('doc2')" />
<xsl:value-of select="concat('c1=', count($doc1/*))"/>
<xsl:value-of select="concat('c2=', count($doc2/*))"/>
按预期运行:
RESOLVE WAS CALLED
RESOLVE WAS CALLED
c1=1c2=1