List child nodes of element XSLT

xml, xslt, xslt-2.0

Solution

Instead of cycling through all children you should rather use templates for the Specs elements you find and turn each into text.

I would use the following stylesheet (it seems you want to generate HTML):

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns="http://www.w3.org/1999/xhtml" 
                              xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" indent="yes"/>  

  <xsl:template match="/">
    <xsl:text disable-output-escaping='yes'>&lt;!DOCTYPE html></xsl:text>
      <html>
      <body>
        <xsl:apply-templates/>
      </body>
      </html>
  </xsl:template>

  <xsl:template match="Specs">
      <xsl:for-each select="*"> <!-- take all descendants of Specs -->
        <p>
          <xsl:value-of select="name()"/>
          <xsl:text> = </xsl:text>

          <!-- this just copies the text() of possible descendants! -->
          <xsl:value-of select="."/> 
        </p>
      </xsl:for-each>
  </xsl:template>

  <!-- do nothing for unmatched text or attribute nodes -->
  <xsl:template match="text()|@*"/>

</xsl:stylesheet>

You will still face a problem with nested Specs like `<Size>` for example. With this template, the output is (minus some additional whitespace):

<p>Size = 70 mm 7 mm</p>

Problem

So I want to list all the child nodes with name and text of Specs node. ``` <Item-Request model="MZ-7TE1T0BW" Supplier-Code="TOMSAM1TB"> <DisplayItem> <Item href="SAM1TBMZ7TE1T0BW.jpg" model="MZ-7TE1T0BW"> <Name>Samsung SSD MZ-7TE1T0BW 1 TB 2.5 inch</Name> <Price>630.99</Price> <SupplierCode>TOMSAM1TB</SupplierCode> <Description/> <Specs> <Capacity>1 TB</Capacity> <Reading>540 MB/s</Reading> <Writing>520 MB/s</Writing> <FormFactor>2.5 "</FormFactor> <Connecor>Sata III</Connecor> <Size> <Width>70 mm</Width> <Height>7 mm</Height> </Size> <Weight>53 g</Weight> </Specs> <Supplier>TOM001</Supplier> <SupplierName>Tom PC Hardware</SupplierName> <Manufacturer>Samsung</Manufacturer> </Item> </DisplayItem> </Item-Request> ``` I cannot do this hard-coded as these are not values that I have readily available and can be added or removed. So I need something that could dynamically list them. So far what I've been able to do is ``` <xsl:for-each select="DisplayItem/Item/Specs"> <xsl:for-each select="node()"> <xsl:value-of select="."/> <br/> </xsl:for-each> </xsl:for-each> ``` The above lists the values on a separate line now I need to be able to display the element name.

Original source