2009-08-14 9 views
5

Ich ziehe, was von meinen Haaren übrig ist, versuchen, eine einfache externe Nachschlagen arbeiten mit Saxon 9.1.0.7.XSLT 2.0 Externe Suche mit Schlüssel() und Dokument()

Ich habe eine einfache Quelldatei dummy.xml:

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

Dann wird die Suchdatei ist 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> 

Was ich Ich versuche zu erreichen, einfach das "Genre" zu ergattern "Wert basierend auf dem Wert" DepartmentCode ".

So sieht meine XSL wie:

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

...


Das Problem, das ich habe, ist, dass ich nichts zurück. Ich zur Zeit nur erhalten

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

ich alle Lookup-Daten verschoben haben Attribute von GenreMapping, die zuvor als Child-Elemente von GenreMapping sein, wenn ich die Vorlage match = „GetGenreMappingObjectsResponse“ eingegeben würde einfach alles auszudrucken von jedem GenreMapping (DepartmentCode, DepartmentName, Genre)!

Ich kann nicht für das Leben von mir herausfinden, was ich falsch mache. Jede helpo/Vorschläge würde sehr geschätzt werden.

bitte den aktuellen Ist-XSLT-Eintrag zu finden.

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

Die TransformationID ist immer und überall 124 (so die korrekte Lookup-Datei geöffnet wird Der Typ ist nur ein Name, den ich bin derzeit nicht verwenden, aber die Absicht hat

.
+0

Welchen XSLT-Compiler verwenden Sie? – Welbog

+0

Saxon-B 9.1.0.7 –

+0

Zahlen. Ich kenne das nicht. Vielleicht wird Tomalak später kommen und dir helfen. Hat die schlüssellose Methode funktioniert? – Welbog

Antwort

7

In XSLT 2.0 gibt es zwei Möglichkeiten, wie Sie tun können, was Sie wollen:

One die Version der key Funktion drei-Parameter ist der dritte Parameter Sie den Wurzelknoten Sie der Schlüssel arbeiten möchten angeben können (. Standardmäßig ist es immer die Wurzel des Hauptdokuments):

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

Eine andere Möglichkeit ist es, die Funktion unter dem key$lookupDoc Knoten zu verwenden:

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

Beide dieser Verfahren in der XSLT 2.0 specification on keys dokumentiert sind, und wird nicht arbeite in XSLT 1.0.

Der Vollständigkeit halber müssen Sie dies neu schreiben, um keine Schlüssel zu verwenden, wenn Sie auf XSLT 1.0 beschränkt sind.

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

Aha! Das Problem ist die select="$lookupDoc" in Ihrem apply-templates Aufruf ruft eine Standardvorlage und nicht die, die Sie erwarten, so dass der Parameter verloren geht.

ändert es dazu:

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

Das Vorlage richtig nennen, und der Schlüssel funktionieren soll.

Also das letzte XSLT Blatt sollte wie folgt aussehen:

<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 dort, Danke für die Antwort. Ich habe bereits versucht (und jetzt erneut), diese beiden (aus dem Master-Vorlage, ich apply-Vorlage mit diesem Formular nicht aufrufen) und beide zurück nichts. Ich bekomme immer noch die leeren Elemente ?! Es muss etwas sein, das ich falsch in der Einrichtung des Schlüssels vielleicht mache? Grüße –

+0

Dies könnte ein spezifisches Problem mit Ihrem XSLT-Compiler sein, aber die Verwendung von '$ lookupDoc/*' sollte Ihre Basen abdecken. – Welbog

+0

Hallo wieder, Mit dem aktualisierten Code bekomme ich keine leeren Elemente mehr, ich bekomme sie voll von Leerzeichen (24 Zeilen wert). Ich bin jetzt wirklich verwirrt. –

0

OK, so ist dies ein bisschen mentale und ich behaupte nicht, es zu verstehen, aber es funktioniert (klingt wie eine Karriere in Software).

Das Problem, das ich hatte, ist, dass, wenn ich die Anwendung Vorlagen anmelde und das externe Dokument als eine Variable übergab es nie irgendwelche Vorlagen auch "Genremaping" genannt.

Also habe ich einen Platzhalter verwendet, um ihn zu fangen, auch beim Aufruf der Anwenden-Vorlagen habe ich den Knoten auf das Kind, an dem ich interessiert war, eingegrenzt. Das war schön, ich könnte den Namen des Knotens ausdrucken siehe "GenreMapping", aber es ging nie in eine Vorlage, die ich "GenreMapping" genannt hatte, sondern stattdessen nur auf die "*" Vorlage.

Das bedeutet, dass meine neue Template-Übereinstimmung für jeden einzelnen GenreMapping-Knoten aufgerufen wird, der also etwas ineffizient ist. Was ich dann erkannte, war alles, was ich tun musste, etwas auszudrucken, wenn ein Prädikat übereinstimmte.

So sieht es aus wie diese nun (ohne Schlüssel verwendet auch immer):

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

All das Ausgangs: Hinweis, der letzte key_value korrekt keinen Code-Eingabe hat, da es keine Übereinstimmung in der ist Nachschlagedokument.

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

Antwort auf einer Postleitzahl. Danke für die Hilfe Welbog.

+0

Ich bin froh, dass Sie eine funktionierende Lösung gefunden haben, obwohl es ein komisches ist. – Welbog