0

How to select the inner value of the element node in xml/xslt in a for-each loop without changing the given xml format.

XML:

<folio name="f1r" wordCount="210" width="1090" height="1500">
<word index="0" x="97" y="128" width="106" height="96">fachys</word>
<word index="1" x="225" y="164" width="58" height="61">ykal</word>
...
</folio>

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html> 
<body>
  <h2>Folio Info</h2>

    <table border="1">
        <tr bgcolor="#9acd32">
          <th style="text-align:left">Folio Name</th>
          <th style="text-align:left">Word Count</th>
          <th style="text-align:left">width</th>
          <th style="text-align:left">height</th>
        </tr>
        <xsl:for-each select="folio">
        <tr>
          <td><xsl:value-of select="@name"/></td>
          <td><xsl:value-of select="@wordCount"/></td>
          <td><xsl:value-of select="@width"/></td>
          <td><xsl:value-of select="@height"/></td>
        </tr>
        </xsl:for-each>
      </table>
    <table border="1">
        <tr bgcolor="#9acd32">
          <th style="text-align:left">index</th>
          <th style="text-align:left">Wordnnnnnnnnnn</th>
          <th style="text-align:left">x loc</th>
          <th style="text-align:left">y loc</th>
          <th style="text-align:left">height</th>
          <th style="text-align:left">width</th>
        </tr>
        <xsl:for-each select="folio/word">
        <tr>
          <td><xsl:value-of select="@index"/></td>
          <td><xsl:value-of select="../word"/></td>
          <td><xsl:value-of select="@x"/></td>
          <td><xsl:value-of select="@y"/></td>
          <td><xsl:value-of select="@height"/></td>
          <td><xsl:value-of select="@width"/></td>
        </tr>
        </xsl:for-each>
      </table>
    </body>
    </html>
    </xsl:template>
    </xsl:stylesheet>

Result:

[1]: https://i.stack.imgur.com/98sBP.png

As you can see it is repeating "fachys" instead of going onto "ykal". It does that for all nodes, ive just screenshotted first five. But the problem is i dont want to just make the value into its own attribute or sub node as all the data is already like this. Its been a while since i was a good at xml so im abit rusty. Any ideas?

jsky
  • 2,225
  • 5
  • 38
  • 54

1 Answers1

0

That doesn't make sense.

<xsl:for-each select="folio/word">
  <!-- ... -->
  <td><xsl:value-of select="../word"/></td>
  <!-- ... -->
</xsl:for-each>

You want

<xsl:for-each select="folio/word">
  <!-- ... -->
  <td><xsl:value-of select="."/></td>
  <!-- ... -->
</xsl:for-each>

The first code goes to the <word> ("for each <word>") and from there, the XPath ../word goes up one level (to <folio>) and selects all <word>s again. And when you give multiple nodes to value-of, it will consider the first node only. That's why you keep getting fachys as the result.

Use the . when you want to output the current node.

Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • thanks. so simple i dont know how i missed that. tried everything else. they should put that on the w3 docs. – jsky Dec 31 '20 at 09:46
  • 1
    @jsky I'm pretty sure it's in the docs. But then again, it's pretty straightforward once you've got a mental model of how navigation works in XSLT. :) – Tomalak Dec 31 '20 at 09:50
  • yeh after checking it i think it was under xpath and i only looked at xml and xslt – jsky Dec 31 '20 at 11:16