我需要使用多个源进行 XSLT 转换以生成一个 XML 文件。
例如:我有一个要转换的 XML 消息,一个要进行转换的 XSL 文件,以及一个由 XSL 文件导入的文档片段。
如果我只使用一个 documentFragment,它就可以工作。点击此链接:
...StringURIResolver
效果很好。但它仅适用于一个文档片段注入(inject)(在 XSL 上仅使用一个 document()
函数作为链接的示例)。以链接的代码为例,我对其进行了一些更改以支持多次注入(inject):
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 被调用,消息“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;
}
如果有解决方案可以为 XSL 的每个 document()
函数调用 URIResolver.resolve()
或合并多个字符串的新方法-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
关于java - 可以多次调用 URIResolver.resolver() 吗?我需要添加多个 documentFragments,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8421348/