Pregunta

Dado el siguiente 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>

¿Cómo puedo obtener "John Doe" de dentro de la corriente/de inicio de sesión comparador?

He intentado lo siguiente:

<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>
¿Fue útil?

Solución

Me gustaría definir una clave para el índice de la gente:

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

El uso de una clave aquí simplemente se mantiene el código limpio, pero usted también puede encontrar que es útil para la eficiencia, si usted está a menudo tener que recuperar los <person> elementos basados en su <login_name> niño.

Me gustaría tener una plantilla que devuelve el formato de nombre de un determinado <person>:

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

Y luego me gustaría hacer:

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

Otros consejos

Quieres current() la función

<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 poco más de limpiador:

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

Si usted necesita para tener acceso a varios usuarios, a continuación, JeniT del <xsl:key /> enfoque es lo ideal.

Aquí es mi alternativa a tomar en él:

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

Se le asigna el seleccionado <person> nodo a una variable, a continuación, utilizamos la concat() función de salida de la primera/última nombres.

También hay un error en el XML de ejemplo.El <person> nodo incorrectamente termina con </preson> (errata)

Una mejor solución podría ser dado de si sabía de la estructura general del documento XML (con nodos raíz, etc.)

Creo que lo que él realmente quería era la sustitución en el partido por la "actual" nodo, no de un partido en la persona de un nodo:

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

Sólo para agregar mis pensamientos a la pila

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

Yo siempre prefiero usar los ejes explícitamente en mi XPath, más detallado, pero claro en mi humilde opinión.

Dependiendo de cómo el resto de los documentos XML se ve (suponiendo que esto es sólo un fragmento) usted puede ser que necesite para limitar la referencia a la "antepasado::la gente", por ejemplo el uso de "ancestro: personas[1]" para forzar a las primeras personas antepasado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top