2009-08-14 9 views
5

Wyciągam resztki włosów, próbując uzyskać prosty zewnętrzny wygląd przy użyciu Saxon 9.1.0.7.XSLT 2.0 Zewnętrzne wyszukiwanie za pomocą klawisza() i dokumentu()

Mam prosty plik źródłowy dummy.xml:

<something> 
    <monkey> 
     <genrecode>AAA</genrecode> 
    </monkey> 
    <monkey> 
     <genrecode>BBB</genrecode> 
    </monkey> 
    <monkey> 
     <genrecode>ZZZ</genrecode> 
    </monkey> 
    <monkey> 
     <genrecode>ZER</genrecode> 
    </monkey> 
</something> 

Następnie plik wyszukiwania jest GenreSet_124.xml:

<GetGenreMappingObjectsResponse> 
    <tuple> 
     <old> 
     <GenreMapping DepartmentCode="AAA" 
         DepartmentName="AND - NEWS AND CURRENT AFFAIRS" 
         Genre="10 - NEWS"/> 
     </old> 
    </tuple> 
    <tuple> 
     <old> 
     <GenreMapping DepartmentCode="BBB" 
         DepartmentName="AND - NEWS AND CURRENT AFFAIRS" 
         Genre="11 - NEWS"/> 
     </old> 
    </tuple> 

    ... lots more 
</GetGenreMappingObjectsResponse> 

Co ja” Próbuję osiągnąć to po prostu zdobyć "Gatunek" "wartość oparta na wartości" Kod departamentu ".

Więc moja XSL wygląda następująco:

... 
<!-- Set up the genre lookup key --> 
<xsl:key name="genre-lookup" match="GenreMapping" use="@DepartmentCode"/> 


<xsl:variable name="lookupDoc" select="document('GenreSet_124.xml')"/> 

<xsl:template match="/something"> 
<stuff> 
    <xsl:for-each select="monkey"> 
     <Genre> 

     <xsl:apply-templates select="$lookupDoc"> 
     <xsl:with-param name="curr-label" select="genrecode"/> 
     </xsl:apply-templates> 

     </Genre> 
    </xsl:for-each> 
</stuff> 
</xsl:template> 

<xsl:template match="GetGenreMappingObjectsResponse"> 
    <xsl:param name="curr-genrecode"/> 

    <xsl:value-of select="key('genre-lookup', $curr-genrecode)/@Genre"/> 

</xsl:template> 

...


Kwestia, że ​​mam to, że nic nie mogę z powrotem. Obecnie po prostu

<?xml version="1.0" encoding="UTF-8"?> 
<stuff> 
    <Genre/> 
    <Genre/> 
    <Genre/> 
    <Genre/> 
</stuff> 

I zostały przeniesione wszystkie dane odnośników być atrybuty GenreMapping, wcześniej jako elementów potomnych GenreMapping gdy wszedłem do template match = „GetGenreMappingObjectsResponse” to po prostu wydrukować cały tekst z każdego GenreMapping (Kod departamentu, nazwa departamentu, gatunek)!

Nie mogę do końca życia zrozumieć, co robię źle. Wszelkie helpo/sugestie będą bardzo mile widziane.

znajdą się aktualna lista XSLT.

<?xml version="1.0"?> 
<xsl:stylesheet version="2.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

<!-- Define the global parameters --> 
<xsl:param name="TransformationID"/> 
<xsl:param name="TransformationType"/> 

<!-- Specify that XML is the desired output type --> 
<xsl:output method="xml" encoding="UTF-8" indent="yes"/> 

<!-- Set up the genre matching capability --> 
<xsl:key name="genre-lookup" match="GenreMapping" use="@DepartmentCode"/> 

<xsl:variable name="documentPath"><xsl:value-of select="concat('GenreSet_',$TransformationID,'.xml')"/></xsl:variable> 
<xsl:variable name="lookupDoc" select="document($documentPath)"/> 

<!-- Start the first match on the Root level --> 
<xsl:template match="/something"> 
<stuff> 
    <xsl:for-each select="monkey"> 
     <Genre> 
     <xsl:apply-templates select="$lookupDoc/*"> 
     <xsl:with-param name="curr-genrecode" select="string(genrecode)"/> 
     </xsl:apply-templates> 
     </Genre> 
    </xsl:for-each> 
</stuff> 
</xsl:template > 

<xsl:template match="GetGenreMappingObjectsResponse"> 
    <xsl:param name="curr-genrecode"/> 
    <xsl:value-of select="key('genre-lookup', $curr-genrecode, $lookupDoc)/@Genre"/> 
</xsl:template> 
</xsl:stylesheet> 

TransformationID jest sprecyzowane 124 (tak poprawny plik odnośnika jest otwierany typ jest tylko nazwa, że ​​jestem obecnie nie jest używany, ale zamierza

.
+0

Co XSLT kompilator używasz? – Welbog

+0

Saxon B 9.1.0.7 –

+0

rysunkach. Nie znam tego. Może później Tomalak przyjdzie i ci pomoże. Czy metoda bezkluczykowa zadziałała? – Welbog

Odpowiedz

7

W XSLT 2.0 istnieją dwa sposoby, można robić, co chcesz:

Jednym z nich jest wersja trzy-parametr funkcji key trzeci parametr pozwala określić węzeł główny, który ma klucz do pracy na (. domyślnie jest zawsze korzeniem dokumentu głównego):

<xsl:value-of select="key('genre-lookup', $curr-genrecode,$lookupDoc)/@Genre"/> 

Innym sposobem jest użycie funkcji key pod $lookupDoc węzła:

<xsl:value-of select="$lookupDoc/key('genre-lookup', $curr-genrecode)/@Genre"/> 

Obie te metody są udokumentowane w XSLT 2.0 specification on keys i nie będzie działa w XSLT 1.0.

W celu uzupełnienia, musisz przepisać to, aby nie używać klawiszy, jeśli jesteś ograniczony do XSLT 1.0.

<xsl:value-of select="$lookupDoc//GenreMapping[@DepartmentCode = $curr-genrecode]/@Genre"/> 

Aha! Problemem jest select="$lookupDoc" w wywołaniu apply-templates dzwoni szablon domyślny raczej niż ten, można się spodziewać, więc parametr jest zagubienie.

zmienić go na to:

<xsl:apply-templates select="$lookupDoc/*"> 
    <xsl:with-param name="curr-genrecode" select="string(genrecode)"/> 
</xsl:apply-templates> 

Że wezwie szablon prawidłowo, a klucz powinien działać.

więc ostateczna arkusz XSLT powinien wyglądać mniej więcej tak:

<xsl:variable name="lookupDoc" select="document('XMLFile2.xml')"/> 
    <xsl:key name="genre-lookup" match="GenreMapping" use="@DepartmentCode"/> 
    <xsl:template match="/something"> 
    <stuff> 
     <xsl:for-each select="monkey"> 
     <Genre> 
      <xsl:apply-templates select="$lookupDoc/*"> 
      <xsl:with-param name="curr-genrecode" select="string(genrecode)"/> 
      </xsl:apply-templates> 
     </Genre> 
     </xsl:for-each> 
    </stuff> 
    </xsl:template> 
    <xsl:template match="GetGenreMappingObjectsResponse"> 
    <xsl:param name="curr-genrecode"/> 
    <xsl:value-of select="key('genre-lookup',$curr-genrecode,$lookupDoc)/@Genre"/> 
    </xsl:template> 

(Source of information)

+0

HI tam, Dzięki za odpowiedź. Próbowałem już (i teraz ponowić) oba te elementy (z poziomu szablonu głównego, nie nazywam szablonu stosowania za pomocą tego formularza) i obie nic nie zwracają. Nadal dostaję puste elementy ?! Czy może być coś, co robię źle w ustawieniu klucza? Pozdrawiam –

+0

To może być specyficzny problem z twoim kompilatorem XSLT, ale użycie '$ lookupDoc/*' powinno objąć twoje bazy. – Welbog

+0

Witaj ponownie, Używanie zaktualizowanego kodu Nie mam już pustych elementów Otrzymuję je pełne białych znaków (24 linii wartości). Jestem teraz naprawdę zdziwiony. –

0

OK, więc jest to trochę psychiczny a ja nie twierdzę, żeby go zrozumieć, ale działa (brzmi jak kariera w oprogramowaniu).

Problem miałem jest to, że kiedy wezwać apply-templates i przechodzą w dokumencie zewnętrznym jako zmiennej nigdy nie dopasowane żadnych szablonów nawet te, zwane „Genremapping”.

Więc użyłem symbolu wieloznacznego, aby go złapać, także podczas wywoływania szablonów zastosowania zawęziłem węzeł ustawiony na dziecko, które mnie interesowało. To było dość dziwne, mogłem wydrukować nazwę węzła i zobacz "GenreMapping", ale nigdy nie wszedł do żadnego szablonu, który nazwał "GenreMapping" wybierając zamiast tego tylko iść do "*" szablonu.

Oznacza to, że mój nowy szablon mecz jest wywoływana dla każdego węzła pojedynczego GenreMapping jest więc może być trochę nieefektywne. Wtedy zdałem sobie sprawę, że wystarczy tylko wydrukować, jeśli orzeczenie się zgadza.

Tak wygląda to teraz (bez klucza używanego w ogóle):

... 
<xsl:template match="/something"> 
<stuff> 
    <xsl:for-each select="monkey"> 
     <Genre> 
     <key_value><xsl:value-of select="genrecode"/></key_value> 
     <xsl:variable name="key_val"><xsl:value-of select="genrecode"/></xsl:variable> 
     <code> 
     <xsl:apply-templates select="$lookupDoc/*/*/*/*"> 
     <xsl:with-param name="curr-genrecode" select="string(genrecode)"/> 
     </xsl:apply-templates> 

     </code> 
     </Genre> 
    </xsl:for-each> 
</stuff> 
</xsl:template > 


<xsl:template match="*"> 
    <xsl:param name="curr-genrecode"/> 
    <xsl:value-of select=".[@DepartmentCode = $curr-genrecode]/@Genre"/> 
</xsl:template> 
... 

Wszystko którego wyjście: Uwaga, ostatni key_value właściwie nie posiada wpisu kodu, ponieważ nie ma odpowiednika w dokument przeglądowy.

<?xml version="1.0" encoding="UTF-8"?> 
<stuff xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <Genre> 
     <key_value>AAA</key_value> 
     <code>10 - NEWS</code> 
    </Genre> 
    <Genre> 
     <key_value>AAA</key_value> 
     <code>10 - NEWS</code> 
    </Genre> 
    <Genre> 
     <key_value>BBB</key_value> 
     <code>11 - NEWS</code> 
    </Genre> 
    <Genre> 
     <key_value>SVVS</key_value> 
     <code/> 
    </Genre> 
</stuff> 

Odpowiedź na kod pocztowy. Dzięki za pomoc Welbog.

+0

Cieszę się, że znalazłeś działające rozwiązanie, mimo że jest dziwne. – Welbog

Powiązane problemy