2017-11-24 3 views
1

Ich habe zwei Schlüssel in einem XML, wobei ein Schlüssel verwendet wird, um den Vornamen zu finden und der zweite Schlüssel wird verwendet, um den Nachnamen zu finden. Meine erwartete Ausgabe ist, wenn, i Mitarbeiter Vorname und Nachname mit 1 unter mehreren Auftragnehmer Vorname Nachname übereinstimmen, muss ich die Agentur Namen abzurufen, die in der Auftragnehmer xml vorhanden ist, und verwenden Sie es in MitarbeiterSchlüssel mit mehreren Bedingungen xslt

Eingang

<listofdata> 
    <data> 
    <Type>Employee</Type> 
    <firstname>x</firstname> 
    <lastname>y</lastname> 
    </data> 
    <data> 
    <Type>Contractor</Type> 
    <firstname>x</firstname> 
    <lastname>y</lastname> 
    <agency>z</agency> 
    </data> 
    <data> 
    <Type>Contractor</Type> 
    <firstname>x</firstname> 
    <lastname>x</lastname> 
    <agency>a</agency> 
    </data> 
    <data> 
    <Type>Contractor</Type> 
    <firstname>a</firstname> 
    <lastname>y</lastname> 
    <agency>b</agency> 
    </data> 
    </listofdata> 

Ausgabe

<listofdata> 
    <data> 
    <Type>Employee</Type> 
    <firstname>x</firstname> 
    <lastname>y</lastname> 
    <agency>z</agency> 
    </data> 
    <data> 
    <Type>Contractor</Type> 
    <firstname>x</firstname> 
    <lastname>y</lastname> 
    <agency>z</agency> 
    </data> 
    <data> 
    <Type>Contractor</Type> 
    <firstname>x</firstname> 
    <lastname>x</lastname> 
    <agency>a</agency> 
    </data> 
    <data> 
    <Type>Contractor</Type> 
    <firstname>a</firstname> 
    <lastname>y</lastname> 
    <agency>b</agency> 
    </data> 
    </listofdata> 

XSLT:

<!--get the agency --> 
<xsl:template name="getagency"> 
    <xsl:variable name="match" select="key('firstname', firstname) 
and key('lastname', lastname)" /> 
<xsl:if test="$match"> 
        <xsl:variable name="lastnamevar" select=" 
[key('lastname', lastname)] [key('fistname', firstname)]/agency" /> 
    <agency> 
     <xsl:value-of select="$lastnamevar" /> 
    </agency> 
    </xsl:if> 
</xsl:template> 

Ich rufe eine Vorlage immer dann an, wenn ich auf 'Mitarbeiter' stoße, um Agentur zu bekommen, und mein Vorname und Nachname sind Schlüssel, die nach Vornamen und Nachnamen in Subunternehmern suchen. Problem ist in der Lage, Boolean wahr falsch oben zu erhalten, wenn, aber nicht in der Lage, genaue Agenturwert zu erhalten, nicht in der Lage zu sagen, dass die Agentur, wo Vorname und Nachname übereinstimmt, wenn ich Single-Taste verwenden, funktioniert die Achsen, aber nicht sicher wie man es für 2 Schlüssel

+0

Vielen Dank, Ich dachte über die Verwendung von concat, aber nicht bewusst, dass ich nach a + b = a + b anstelle von a = a und b = b suchen kann. Danke, das hat geholfen, mehr Klarheit zu bringen. Ich weiß nicht, wie ich das vorher ignoriert habe. Ich benutze xlst2, also benutze das. Ich mache noch ein paar Tests und markiere es als akzeptierte Antwort. Vielen Dank – Krish

Antwort

1

ich glaube, Sie wollen einen zusammengesetzten Schlüssel, so in XSLT 3 unter Verwendung von Saxon 9.8 (beliebige Edition) oder Altova 2017 oder 2018 Sie

<xsl:key name="contract" match="data[Type = 'Contractor']" composite="yes" use="firstname, lastname"/> 

<xsl:mode on-no-match="shallow-copy"/> 

<xsl:template match="data[Type = 'Employee' and key('contract', (firstname, lastname))]/node()[last()]"> 
    <xsl:next-match/> 
    <xsl:copy-of select="key('contract', ../(firstname, lastname))/agency"/> 
</xsl:template> 

in XSLT 2 funktioniert direkt nutzen könnten Sie können die beiden Elementwerte im Schlüssel mit zB verketten <xsl:key name="contract" match="data[Type = 'Contractor']" use="concat(firstname, '|', lastname)"/> und verwenden z.B.

<xsl:template match="data[Type = 'Employee' and key('contract', concat(firstname, '|', lastname))]/node()[last()]"> 
    <xsl:next-match/> 
    <xsl:copy-of select="key('contract', concat(../firstname, '|', ../lastname))/agency"/> 
</xsl:template> 

und natürlich müssen Sie die Identität Transformation Vorlage buchstabieren.

2

Neben den von @MartinHonnen vorgeschlagenen Lösungen ist es möglich, zwei Sätze von Werten zu verwenden, die von verschiedenen Schlüsseln gefunden wurden, und ihren Schnittpunkt zu bilden. In XSLT 2.0 können Sie mit dem intersect Betreiber dies direkt tun:

key('firstName', 'John') intersect key('lastName', 'Smith') 

XPath 1.0 keinen Operator für Schnittmenge hat, aber es gibt eine gewundene Lösung basierend auf Vereinigungs:

<xsl:variable name="X" select="key('firstName', 'John')"/> 
<xsl:variable name="Y" select="key('lastName', 'Smith')"/> 
... select="$X[count(.|$Y) = count($Y)]"/>