Transform XML to HTML table

时间:2015-10-06 08:40:45

标签: html xml xslt xpath

I want to transform xml to html using xsl but I'm struggling to make it work although it should be pretty straightforward.

Input XML:

<EEExport Version="201510" Language="International" LanguageIsoCode="int-INT">
  <Navigation>
    <Navigation Name="Navigation" NavigationID="E905C889-63EF-431E-BD74-A470685F65E0">
      <Navigation Name="Oven" NavigationID="B929861A-57D1-4C20-BE2C-0DC006F4D6CE">
      </Navigation>
      <Navigation Name="Cooker" NavigationID="643B0A58-D83B-4D8F-9E97-A5C8E572B1E5">
      </Navigation>
      <Navigation Name="Dishwasher" NavigationID="FAB9B544-109D-4B83-A6E4-25114E1D25BA">
        <Product ProductID="887B5B3C-F9C7-4F4A-8E0B-1FC62830C508">
          <MasterData>
            <Brand>Brand1</Brand>
            <ProductCode>911 424 310</ProductCode>
            <Category ID="B1679547-77B2">Dish_Washer</Category>
          </MasterData>
          <Containers>
            <Container ContainerName="STechSpec_Dish_Washer">
              <Attribute AttributeID="36214A61" Name="ModelD" >F55600IM0P</Attribute>
              <Attribute AttributeID="C3C36430" Name="BarCode" >7332543317288</Attribute>
              <Attribute AttributeID="0B38C70E" Name="CutleryShelves" >None</Attribute>
          </Container>
        </Containers>
      </Product>
      <Product ProductID="D4DB8281-42D7-4240-8731-220FD728481D">
          <MasterData>
            <Brand>Brand2</Brand>
            <ProductCode>911 536 090</ProductCode>
            <Category ID="B1679547-77B2">Dish_Washer</Category>
          </MasterData>
          <Containers>
            <Container ContainerName="STechSpec_Dish_Washer">
              <Attribute AttributeID="36214A61" Name="ModelD" >ZDT26020FA</Attribute>
              <Attribute AttributeID="C3C36430" Name="BarCode" >7332543397303</Attribute>
              <Attribute AttributeID="0B38C70E" Name="CutleryShelves" >Cutlery Drawer</Attribute>
            </Container>
          </Containers>
        </Product>
      </Navigation>
    </Navigation>
  </Navigation>
</EEExport>

I only want to show specific product fields of category 'Dishwasher'. Desired output:

<html>
  <body>
    <table border="1">
      <tr bgcolor="#e3e3e3">
        <th>Brand</th>
        <th>Product Code</th>
        <th>Model D</th>
        <th>Cutlery Shelves</th>
      </tr>
      <tr>
        <td>Brand1</td>
        <td>911 424 310</td>
        <td>F55600IM0P</td>
        <td>None</td>
      </tr>
      <tr>
        <td>Brand2</td>
        <td>911 536 090</td>
        <td>ZDT26020FA</td>
        <td>Cutlery Drawer</td>
      </tr>
    </table>
  </body>
</html>

Current xsl:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
    <table border="1">
      <tr bgcolor="#e3e3e3">
        <th>Brand</th>
        <th>Product Code</th>
        <th>Model D</th>
        <th>Cutlery Shelves</th>
      </tr>
      <xsl:for-each select="/EEExport/Navigation/Navigation/Navigation[@Name='Dishwasher']/Product">
        <tr>
          <td><xsl:value-of select="/Masterdata/Brand"/></td>
          <td><xsl:value-of select="/Masterdata/ProductCode"/></td>
          <td><xsl:value-of select="/Containers/Container/Attribute[@Name='ModelD']"/></td>
          <td><xsl:value-of select="/Containers/Container/Attribute[@Name='CutleryShelves']"/></td>
        </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

Obviously I'm doing something wrong. Any help is greatly appreciated.

1 个答案:

答案 0 :(得分:1)

There are two problems with your XSLT.

Firstly, when you start an XPath expression with / then this represents the top-level document node, and so the search will be relative to that, and not to the node you are currently positioned on.

So instead of doing this:

<xsl:value-of select="/Masterdata/Brand"/>

Do this:

<xsl:value-of select="Masterdata/Brand"/>

Having said that, this leads on to the second issue. XML and XSLT are case sensitive. In your XML you use MasterData, but in your XSLT you refer to Masterdata. So, the expression should actually be like this:

<xsl:value-of select="MasterData/Brand"/>

Try this XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
    <table border="1">
      <tr bgcolor="#e3e3e3">
        <th>Brand</th>
        <th>Product Code</th>
        <th>Model D</th>
        <th>Cutlery Shelves</th>
      </tr>
      <xsl:for-each select="EEExport/Navigation/Navigation/Navigation[@Name='Dishwasher']/Product">
        <tr>
          <td><xsl:value-of select="MasterData/Brand"/></td>
          <td><xsl:value-of select="MasterData/ProductCode"/></td>
          <td><xsl:value-of select="Containers/Container/Attribute[@Name='ModelD']"/></td>
          <td><xsl:value-of select="Containers/Container/Attribute[@Name='CutleryShelves']"/></td>
        </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>