Domanda

Dato il seguente 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>

Come posso ottenere "John Doe" dal matcher corrente/login?

Ho provato quanto segue:

<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>
È stato utile?

Soluzione

Definirei una chiave per indicizzare le persone:

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

L'uso di una chiave qui mantiene semplicemente il codice pulito, ma potresti anche trovarlo utile per l'efficienza se devi spesso recuperare il codice <person> elementi basati sul loro <login_name> bambino.

Avrei un modello che restituisse il nome formattato di un dato <person>:

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

E poi farei:

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

Altri suggerimenti

Tu vuoi current() funzione

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

o un po' più pulito:

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

Se devi accedere a più utenti, allora JeniT <xsl:key /> approccio è l'ideale.

Ecco la mia interpretazione alternativa:

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

Assegniamo il selezionato <person> nodo a una variabile, quindi usiamo il file concat() funzione per emettere il nome/cognome.

C'è anche un errore nel tuo XML di esempio.IL <person> il nodo termina erroneamente con </preson> (errore di battitura)

Una soluzione migliore potrebbe essere fornita se conoscessimo la struttura complessiva del documento XML (con nodi root, ecc.)

Penso che ciò che in realtà voleva fosse la sostituzione nella corrispondenza del nodo "corrente", non una corrispondenza nel nodo persona:

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

Giusto per aggiungere i miei pensieri allo stack

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

Preferisco sempre utilizzare gli assi esplicitamente nel mio XPath, più dettagliato ma più chiaro IMHO.

A seconda dell'aspetto del resto dei documenti XML (assumendo che si tratti solo di un frammento) potrebbe essere necessario vincolare il riferimento a "ancestor::people", ad esempio utilizzando "ancestor::people[1]" per vincolare alle prime persone antenato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top