Можно ли заставить URIResolver.resolver() вызываться более одного раза? Мне нужно добавить несколько documentFragments

Мне нужно сделать XSLT-преобразование, используя несколько источников, чтобы получить один XML-файл.

Например: у меня есть сообщение XML для преобразования, файл XSL для преобразования и фрагмент документа, импортированный файлом XSL.

Если я использую только один documentFragment, он работает. По этой ссылке:

... StringURIResolver отлично работает. Но это работает только для одной инъекции фрагмента документа (используя только ОДНУ функцию document() на XSL в качестве примера ссылки). Следуя коду ссылки в качестве примера, я внес в него некоторые изменения для поддержки множественных инъекций:

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-файлов с одним, используемым для преобразования, я буду признателен.


person Pablo Thiele    schedule 07.12.2011    source источник


Ответы (1)


Вы уверены, что используете все три переменные где-то в таблице стилей? Это должно работать до тех пор, пока они доступны. (Создания переменной недостаточно.)

Например, я включил в свою 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
person Wayne    schedule 07.12.2011
comment
Я согласен - единственное объяснение, которое я могу придумать для того, чтобы URIResolver не вызывался, заключается в том, что переменная никогда не оценивается, потому что на нее никогда не ссылаются. - person Michael Kay; 08.12.2011
comment
Ивбурк, большое спасибо! Вы правы. Овертайм ослепляет меня из-за одной такой ошибки. Я делаю тест Junit и разрешаю тысячу раз, и теперь все работает. Моя ошибка заключается в неправильном имени значения в данных выбора xsl. Спасибо, Михаил. - person Pablo Thiele; 08.12.2011