Search code examples
xmlxslt

xsl:for-each only returns the first node


I'm having some troubles with XSLT. I want to output each subs property from this

<subscritores>
  <subs ref="Guicky"/>
  <subs ref="Daisy"/>
</subscritores>

Basically my problem is that xsl:for-each is only getting me the first attribute @subs. And I have the same problem with the administradores/@ref

<administradores>
  <admin ref="Guicky"/>
  <admin ref="Daisy"/>
</administradores>

This is my XML code:

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
  <!DOCTYPE xml_tube SYSTEM 
       "C:tp2\Um utilizador\Utilizador\xml__tube.dtd">    
  <?xml-stylesheet type="text/xsl" href="utilizadorG.xsl" ?> 
    
  <xml_tube>
    <playlist>
      <lista owner="Guicky" dataIns="2016-10-24" id="PV1">
        <titulo>BEST MUSIC.</titulo>
        <descricao>Compilation of my favourite music videos.</descricao>
        <gostosL gostouL="Guicky"/>
        <links_vid vid="Vid2"/>
        <links_vid vid="Vid3"/>
        <administradores>
          <admin ref="Guicky"/>
          <admin ref="Daisy"/>
        </administradores>
        <editores>
          <editor ref="Guicky"/>
        </editores>
        <subscritores>
          <subs ref="Daisy"/>
          <subs ref="Anabela65"/>
        </subscritores>
      </lista>
      <lista owner="Anabela65" dataIns="2016-02-29" id="PV2">
         <titulo>Cooking Lessons!</titulo>
         <descricao>Cooking lesson's with Guicky's mom!</descricao>
         <links_vid vid="Vid4"/>
         <administradores>
           <admin ref="Anabela65"/>
           <admin ref="Guicky"/>
         </administradores>
         <editores>
           <editor ref="Anabela65"/>
         </editores>
         <subscritores>
           <subs ref="Guicky"/>
           <subs ref="Daisy"/>
         </subscritores>
      </lista>
    </playlist>
    <comentarios>
      <comentario id="C1" refV="Vid1" user="Guicky" data="2016-10-23">
        <text>AHAHAHAHA, bom vídeo.</text>
        <gosto gostou="Daisy"/>
        <respostas>
          <texto autor="Daisy">Grande clássico!</texto>
        </respostas>
      </comentario>
      <comentario id="C2" refL="Vid2" user="Anabela65" data="2016-10-22">
        <text>Timmy timmy timmy turner...</text>
        <gosto gostou="Guicky"/>
        <gosto gostou="Daisy"/>
        <respostas>
          <texto autor="Guicky">U know it.</texto>
          <resposta autor="Daisy">LOL!</resposta>
        </respostas>
      </comentario>
    </comentarios>
  </xml_tube>`

This is my XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:output doctype-public="-//W3C//DTD XHTML 1.1//EN"
            doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" />
                   
<xsl:template match="/">
  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="eng">
    <head>
     <title>My XML Tube</title>
     <link rel="stylesheet" type="text/css" href="XML_Tube.css" charset="UTF-8"/>
    </head>
    <body>
      <h1 id="lala">Playlists</h1>
      <section>
        <xsl:for-each select="xml_tube/playlist/lista">
          <article class="list">
            <figure>
              <xsl:element name="img">
                <xsl:attribute name="src">
                  <xsl:value-of select="thumbnail/@link"/>
                </xsl:attribute>
                <xsl:attribute name="width">50%</xsl:attribute>
                <xsl:attribute name="height">auto</xsl:attribute>
              </xsl:element>
              <figcaption>
 <a href="https://goo.gle"><xsl:value-of select="titulo"/></a>
 <p>Nome de utilizador:<xsl:value-of select="@owner"/></p>
 <p>Descrição:<xsl:value-of select="descricao"/></p>
 <p>Admin:   <xsl:value-of select="administradores/admin/@ref"/></p>
 <p>Editores: <xsl:value-of select="editores/editor/@ref"/></p>
 <p>Subscritores:<xsl:value-of 
                               select="subscritores/subs/@ref"/>
     <xsl:text></xsl:text></p>
              </figcaption>
            </figure>
          </article>
        </xsl:for-each>
      </section>
    </body>
   </html>
  </xsl:template>
 </xsl:stylesheet>

I'm portuguese and this is part of a school work, I didn't had time to translate every single node, but I think that shouldn't be a problem. Anyway, thanks in advance!

My expected output is:

Subscritores: Daisy
Subscritores: Anabela

Solution

  • In XSLT 1.0 - which is apparently what you're using - the xsl:value-of instruction returns the value of only the first node in the selected node-set.

    If you want to list all the values, you need to get them one-by-one: e.g. instead of:

    <xsl:value-of select="administradores/admin/@ref"/>
    

    use:

    <xsl:for-each select="administradores/admin">
        <xsl:value-of select="@ref" />
        <xsl:text> </xsl:text>
    </xsl:for-each>