Передать документ в качестве параметра в XSL Translation в Java - PullRequest
7 голосов
/ 17 января 2012

Я работаю над дополнительной интернационализацией в моем XSL.Я видел множество примеров создания файла dictionary.xml и загрузки его в мой XSL через документ ('dictionary.xml').Я хочу сделать что-то похожее, но я не хочу создавать и хранить файл dictionary.xml на диске, я бы предпочел построить его из SQL при запуске сервера и сохранить объект Document в памяти на Java.Затем я хотел бы передать документ словаря в качестве параметра преобразователю, чтобы моя функция перевода XSL могла его использовать.Однако, похоже, он не работает.

Соответствующий код Java:

Document dictionary = TranslationDictionary.getDictionaryDocument();
transformer.setParameter("dictionary", dictionary);

Содержимое документа словаря:

<dictionary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <translatedString dictionaryId="BASIC_DETAILS">
        <language id="es" value="Detalles B&#225;sicos"/>
    </translatedString >
    <translatedString dictionaryId="VEHICLE_INFORMATION">
        <language id="es" value="Informaci&#243;n del Veh&#237;culo"/>
    </translatedString >
    <translatedString dictionaryId="STRUCTURE">
        <language id="es" value="Estructura"/>
    </translatedString >
    <translatedString dictionaryId="DRIVER_INFORMATION">
        <language id="es" value="Informaci&#243;n del Conductor"/>
    </translatedString >
    <translatedString dictionaryId="MAINTENANCE_AND_FEUL">
        <language id="es" value="Mantenimiento &amp; Combustible"/>
    </translatedString >
    <translatedString dictionaryId="PURCHASING">
        <language id="es" value="Compra"/>
    </translatedString >
</dictionary>

Файл XSL:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://www.test.com">
    <xsl:param name="dictionary"/>
    <xsl:param name="language" select="'es'"/>


<xsl:template match="/">
<xsl:message>
    <xsl:copy-of select="$dictionary/dictionary/translatedString[@dictionaryId='BASIC_DETAILS']/language[@id='es']/@value"/>
</xsl:message>

</xsl:template>

Но я ничего не понимаю.Я попытался просто сделать копию $ document / document, чтобы подтвердить, что у меня нет проблемы с xpath, и это не так, потому что это дает мне копию полного документа.Как будто XSL видит словарь в виде строки вместо узла.Есть какие-нибудь подсказки?

Ответы [ 4 ]

8 голосов
/ 17 января 2012

Используйте URIResolver вместо параметра.Сначала создайте преобразователь следующим образом:

public class DocURIResolver implements URIResolver {

    final Map<String, Document> documents;

    public DocURIResolver(final Map<String, Document> documents) {
        this.documents = documents;
    }

    public Source resolve(final String href, final String base) {
        final Document doc = documents.get(href);
        return (doc != null) ? new DOMSource(doc) : null;
    }
}

Используйте его следующим образом:

Document dictionary = TranslationDictionary.getDictionaryDocument();
Map<String, Document> docs = new HashMap<String, Document>();
docs.put("dictionary", dictionary);
// transformer is your javax.xml.transform.Transformer
transformer.setURIResolver(new DocURIResolver(docs));

И укажите его в таблице стилей по имени:

<xsl:variable name="dict" select="document('dictionary')"/>

Thisэто просто игрушечный пример, конечно.Вы можете сделать свой URIResolver настолько полнофункциональным, насколько это необходимо.

4 голосов
/ 17 января 2012

Хорошо, я сделал скелетную копию вашего кода. Это будет звучать странно, но после того, как вы создадите документ словаря в коде Java и перед тем, как установить его в качестве параметра для преобразователя, просто вызовите метод:

dictionary.getDocumentElement();

тогда это работает! Похоже, ошибка в том, что saxon обрабатывает параметр, являющийся документом, где требуется какая-то инициализация, которая еще не была выполнена? Я не копаюсь в отладчике.

3 голосов
/ 17 января 2012

Передача узла DOM Document в качестве параметра саксонскому преобразованию должна работать (долгое время DOM не самое эффективное представление дерева, но оно должно работать).Так следует передать DOMSource, который оборачивает DOM Document.Я обычно начинаю с выполнения xsl: copy-of select = "$ doc", и вы, кажется, сделали это и подтвердили, что значение передается правильно.Если вы ничего не получаете в ответ на выбор XPath в документе, это обычно означает, что выражения XPath неверны.Наиболее распространенные причины - забыть о корневом (документном) узле и забыть о пространствах имен.Но я боюсь, что в коде, который вы нам показали, нет никаких свидетельств таких ошибок - при условии, что DOM отражает XML, который вы показали в своем сообщении.

В вашем сообщении предполагается, что вы создали документ DOM программным способом.Возможно, вы создали DOM, который Saxon по какой-то причине не может обработать: интерфейсы DOM не очень надежны, и иногда возникают трудности, когда люди используют реализацию DOM, которая не была протестирована с Saxon.

Вы также можете протестировать свою таблицу стилей, запустив ее из командной строки - вы можете указать значение параметра $ dictionary с помощью + dictionary = dict.xml (начальный «+» заставляет ее распознаваться как имя файла, который требуетсябыть проанализированным).

0 голосов
/ 17 января 2012

Меняется ли

select="$dictionary

до

select="node-set($dictionary)

помочь?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...