java - 可以多次调用 URIResolver.resolver() 吗?我需要添加多个 documentFragments

标签 java xml xslt saxon

我需要使用多个源进行 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/

相关文章:

java - Cassandra 的一致性

c# - 在 XDocument 中设置根命名空间前缀

c# - XML 验证 : decimal attribute value starting with a space

c# - 在 C# 中将 Soap XML 解析为对象

xslt - 需要帮助理解 - XPath/XSLT 中的上下文节点和当前节点

java - JBOSS 在读取大型 XML 时重新启动

java - 计时器类通过 JFrame 移动 JLabel!为什么 JLabel 文本不能可变?

java - 如何创建对象列表并访问其属性

xml - 使用 Xpath 进行 XSLT 处理的说明

java - android ping InetAddress 和 editText