2012-01-16 18 views
7

Pracuję nad dodaniem internacjonalizacji do mojego XSL. Widziałem mnóstwo przykładów tworzenia pliku dictionary.xml i ładowania go do mojego XSL za pośrednictwem dokumentu ("dictionary.xml"). Chcę zrobić coś podobnego, ale nie chcę tworzyć i przechowywać pliku dictionary.xml na dysku, wolałbym go skompilować z SQL podczas uruchamiania serwera i przechowywać obiekt Document w pamięci w Javie. Chciałbym następnie przekazać dokument słownikowy jako parametr do transformatora, aby moja funkcja tłumaczenia XSL mogła z niego korzystać. Wydaje się jednak, że nie działa.Przekaż dokument jako parametr do tłumaczenia XSL w Javie

odpowiedniego kodu Java:

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

Słownik treści dokumentu:

<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> 

Plik 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> 

Ale ja nic. Próbowałem po prostu zrobić kopię $ dokumentu/dokumentu, aby potwierdzić, że nie mam problemu z xpath, a to nie jest to, ponieważ to daje mi kopię pełnego dokumentu. To tak, jakby XSL widział słownik $ jako ciąg zamiast węzła. Jakieś wskazówki?

+0

Używam Saxon9 jako mojego XSLT, jeśli to pomaga –

+0

To pomaga i wskazuje na fakt, że to pytanie jest specyficzne dla procesora XSLT i jako takie należy do znacznika "xsltprocessor". –

Odpowiedz

4

OK, zrobiłem kopię kodu ze skeletonu. Jest to zabrzmi dziwacznie, ale po utworzeniu dokumentu słownika w kodzie Java i przed ustawieniem go jako parametr dla transformatora, po prostu wywołać metodę:

dictionary.getDocumentElement(); 

to działa! Wygląda jak błąd w sposobie, w jaki sakson radzi sobie z parametrem jakim jest dokument, gdzie wymaga pewnego rodzaju inicjalizacji, która nie została wykonana? Nie zaglądam do debuggera.

+0

Próbowałem inny sposób tworzenia dokumentu DOM, a następnie zauważyłem, że chociaż w wiadomości XSL elementem głównym był "słownik", jeśli napisałem dokument na dysku, był to "Słownik". Po zmianie xpath zadziałało. Dzięki! –

-2

Czy zmieniając

select="$dictionary 

do

select="node-set($dictionary) 

pomoc?

+0

Nie pomaga –

+0

O czym ty mówisz? Jeśli wystąpił błąd w analizatorze składni, który powodował, że słownik $ z jakiegoś powodu był traktowany jako wartość skalarna, a nie jako zbiór węzłów, wówczas zidentyfikowałaby przyczynę problemu. Tak się złożyło, że jego zachowanie było spowodowane przez błąd w parserze saksonów (jak się dowiedziałem i następnie opublikowałem), po prostu nie ten konkretny. – user467257

+0

"zidentyfikował przyczynę problemu" - i potencjalnie naprawił to również, powinienem był dodać, gdyby wywołanie zestawu węzłów wymusiło interpretację typu we właściwym formacie (jeśli przyczyną była interpretacja typu). – user467257

8

Zamiast parametru używaj parametru URIResolver. Najpierw utwórz resolwer takiego:

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; 
    } 
} 

używać go tak:

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)); 

i odniesienie go w arkuszu stylów o nazwie:

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

to tylko przykład zabawki, oczywiście. W razie potrzeby możesz ustawić swój URIResolver jako w pełni funkcjonalny.

+0

Wolałbym nie używać niestandardowego URIResolver. Jakieś inne myśli? –

+0

@DannyCohn - Jakiś konkretny powód? –

+0

Wygląda to na dodatkową warstwę złożoności, która nie powinna być konieczna. Jeśli muszę, to zrobię, ale nie sądzę, że to, co robię, jest na tyle złożone, że wymaga URIR, ale chciałbym spróbować czegoś mniejszego - najpierw jest to –

3

Przekazanie węzła dokumentu DOM jako parametru do transformacji Saxona powinno zadziałać (DOM nie jest najwydajniejszą reprezentacją drzewa, przez długą drogę, ale powinien działać). Tak powinno przechodzić DOMSource, które otacza dokument DOM. Zwykle zaczynam od zrobienia xsl: copy-of select = "$ doc" i wydaje się, że to zrobiłeś i potwierdziłeś, że wartość jest poprawnie przekazywana. Jeśli nie dostaniesz niczego w odpowiedzi na zaznaczenia XPath w dokumencie, zazwyczaj oznacza to, że wyrażenia XPath są błędne. Najczęstszymi przyczynami są zapominanie o głównym węźle (dokumencie) i zapominanie o przestrzeniach nazw. Obawiam się jednak, że w kodzie, który nam pokazałeś, nie ma dowodów takich błędów - zakładając, że DOM odzwierciedla XML, który pokazałeś w swoim poście.

Twój post sugeruje programowe utworzenie dokumentu DOM. Możliwe, że stworzyłeś DOM, którego Saxon nie może przetworzyć z jakiegoś powodu: interfejsy DOM nie są bardzo solidne i czasami występują trudności, gdy ludzie używają implementacji DOM, która nie została przetestowana w Saxonie.

Możesz także przetestować swój arkusz stylów, uruchamiając go z wiersza poleceń - możesz podać wartość parametru $ dictionary za pomocą + dictionary = dict.xml (wiodący znak "+" powoduje, że jest rozpoznawany jako nazwa pliku, który musi zostać przeanalizowany).

+0

Mam zamiar spróbować, kiedy wejdę do biura. Mam zamiar także spróbować skonstruować dokument DOM w inny sposób, aby potwierdzić, że jest poprawnie skonstruowany. Mówisz, że DOM nie jest najbardziej wydajną reprezentacją drzewa. Czy możesz polecić coś innego? Jestem na pewno otwarty na to. –

Powiązane problemy