Frage

Bei der folgenden XML:

<current>
  <login_name>jd</login_name>
</current>
<people>
  <person>
    <first>John</first>
    <last>Doe</last>
    <login_name>jd</login_name>
  </preson>
  <person>
    <first>Pierre</first>
    <last>Spring</last>
    <login_name>ps</login_name>
  </preson>
</people>

Wie kann ich "John Doe" aus der aktuellen / login Matcher erhalten?

Ich habe versucht, die folgenden:

<xsl:template match="current/login_name">
  <xsl:value-of select="../people/first[login_name = .]"/>
  <xsl:text> </xsl:text>
  <xsl:value-of select="../people/last[login_name = .]"/>
</xsl:template>
War es hilfreich?

Lösung

ich die Menschen einen Schlüssel zum Index definieren würde:

<xsl:key name="people" match="person" use="login_name" />

Mit einem Schlüssel hier einfach hält den Code sauber, aber man könnte es auch für Effizienz hilfreich, wenn Sie häufig die <person> Elemente auf der Grundlage ihres <login_name> Kind abrufen zu müssen.

Ich würde eine Vorlage, die den formatierten Namen einer bestimmten <person> zurückgegeben:

<xsl:template match="person" mode="name">
  <xsl:value-of select="concat(first, ' ', last)" />
</xsl:template>

Und dann würde ich tun:

<xsl:template match="current/login_name">
  <xsl:apply-templates select="key('people', .)" mode="name" />
</xsl:template>

Andere Tipps

Sie wollen current() Funktion

<xsl:template match="current/login_name">
  <xsl:value-of select="../../people/person[login_name = current()]/first"/>
  <xsl:text> </xsl:text>
  <xsl:value-of select="../../people/person[login_name = current()]/last"/>
</xsl:template>

oder etwas sauberer:

<xsl:template match="current/login_name">
  <xsl:for-each select="../../people/person[login_name = current()]">
    <xsl:value-of select="first"/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="last"/>
  </xsl:for-each>
</xsl:template>

Wenn Sie an mehrere Benutzer zugreifen können, dann JeniT der <xsl:key /> Ansatz ist ideal.

Hier ist meine Alternative nimmt es:

<xsl:template match="current/login_name">
    <xsl:variable name="person" select="//people/person[login_name = .]" />
    <xsl:value-of select="concat($person/first, ' ', $person/last)" />
</xsl:template>

Wir weisen den ausgewählten <person> Knoten auf eine Variable, dann wir die concat() Funktion zur Ausgabe der ersten / letzten Namen verwenden.

Es gibt auch einen Fehler in Ihrem Beispiel XML. Der <person> Knoten fehlerhaft endet mit </preson> (Schreibfehler)

Eine bessere Lösung könnte gegeben werden, wenn wir die Gesamtstruktur des XML-Dokuments wissen (mit Root-Knoten, usw.)

Ich denke, was er wollte eigentlich der Ersatz im Spiel um den „aktuellen“ Knoten war, kein Spiel in der Person Knoten:

<xsl:variable name="login" select="//current/login_name/text()"/>

<xsl:template match="current/login_name">
<xsl:value-of select='concat(../../people/person[login_name=$login]/first," ", ../../people/person[login_name=$login]/last)'/>

</xsl:template>

Nur meine Gedanken zu dem Stapel hinzufügen

<xsl:template match="login_name[parent::current]">
 <xsl:variable name="login" select="text()"/>
 <xsl:value-of select='concat(ancestor::people/child::person[login_name=$login]/child::first/text()," ",ancestor::people/child::person[login_name=$login]/child::last/text())'/>
</xsl:template>

Ich habe immer lieber die Achsen verwenden, explizit in meinem XPath, ausführlicher, aber klarer IMHO.

Je nachdem, wie der Rest des XML-Dokumente aussehen (vorausgesetzt, dies ist nur ein Fragment) Sie können den Verweis beschränken müssen, um zu „Vorfahren :: Menschen“ zum Beispiel mit „Vorfahren :: Menschen [1]“, um zu beschränken, die ersten Menschen Vorfahren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top