Search code examples
htmlxmlxslt

Turn XML with XSLT to aHTML order Table


I need your help. I'm struggle with XSLT: I have for example an XML file like this:

<Adresses>
<Person id="1">
  <Name>Bott</Name>
  <Vorname>Nils</Vorname>
</Person>

<Person id="2">
  <Name>Hubert</Name>
  <Vorname>Hubertus</Vorname>
</Person>

<Person id="3">
  <Name>Large</Name>
  <Vorname>Lars</Vorname>
</Person>

<Numbers>
  <number>
    <id>1</id>
    <tel>12354</tel>
  </number>
  <number>
    <id>3</id>
    <tel>32354</tel>
  </number>
  <number>
    <id>2</id>
    <tel>22354</tel>
  </number>
</Numbers>

</Adresses>

And I have to transform to a order HTML Table. The HTML Table should look like following (Ordering after ID):

<table>
  <tr>
    <th>Name</th>
    <th>Vorname</th>
    <th>Tel</th>
  </tr>
    <tr>
    <th>Bott</th>
    <th>Nils</th>
    <th>12354</th>
  </tr>
</table>

My problem is I don't know how to check: Choose the number where Peron.id = number.id .... It would be really great if someone could give me a full example for this problem. At web search it is always not so complicated in the tutorials ;-( .... I'm learning XSLT and just know some rules like apply-templates match="Person" .... but how is it possible in such a statement to call a other template which select the correct number?

I try to start with that:

<xsl:template match="/">
<html>
<body>
<xsl:for-each select="Adresses/Person">
  <xsl:call-template name="curPos">
  </xsl:call-template>
  <xsl:value-of select="Name"/>
  <xsl:value-of select="Vorname"/>
  </xsl:for-each>
</body>
</html>
</xsl:template>


<xsl:template name="curPos" match="Person">
 <xsl:value-of select="position()"/><br> </br>
</xsl:template>

Solution

  • I have got the following XSLT 2.0 solution for you:

    <xsl:template name="makeTable">
      <table>
        <tr>
            <th>Name</th>
            <th>Vorname</th>
            <th>Tel</th>
        </tr>        
        <xsl:for-each select="/Adresses/Person">
            <tr>
                <td><xsl:value-of select="Name"/></td>
                <td><xsl:value-of select="Vorname"/></td>
                <td><xsl:value-of select="../Numbers/number[id = current()/@id]/tel"/></td>
            </tr>
        </xsl:for-each>    
      </table>   
    </xsl:template>
    

    Now, for the explanation as far as I understand the problem you have is finding the correct XPath expression for selecting the correct telephone number. The most important code snipped in this case is this line:

    <td>
      <xsl:value-of select="../Numbers/number[id = current()/@id]/tel"/>
    </td>
    

    In XSLT 2.0 - I'm not sure about XSLT 1.0 - you can refer to the current loop element with the current() function in an XPath.
    To select the telephone number I filter for the number on the condition of its id being equal to the current loop elements attribute id and then getting this node's child tel to get the actual number.