XSLT to convert XML into Tables
Copy link to clipboard
Copied
Hi,
I'm trying to import my XML data into a table format. After adding an XSL file to my Structure Application as a Preprocessing Stylesheet, and importing my XML instance file with the Template file opened, the "Unknown File Type" error window appeared asking for a file format to Convert From. Picking any one doesn't create a table.
The XSL file tranforms the XML data into an HTML file that has a table with columns corresponding to the XML data. I was thinking using that type of XSL because it renders tables.
Below is the XSL markup:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>Products</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Number</th>
<th>Date</th>
</tr>
<xsl:for-each select="Products/Product">
<tr>
<td><xsl:value-of select="Title"/></td>
<td><xsl:value-of select="Number"/></td>
<td><xsl:value-of select="Date"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Title, Number, and Date are child elements of the Product element, which is a child element of the Products root element in my XML file.
Am I applying the stylesheet correctly here? Am I using the write kind of stylesheet?
Thanks,
zeb
Copy link to clipboard
Copied
Zeb,
It seems there is a little misconseption at work.
XSL Preprocessing is applied when you open an XML file with FrameMaker using the Structure Application that contains the link to the preprocessing stylesheet. It does not work when importing stuff.
If you go ahead this route, you either have to create a table model that FrameMaker automatically understands or (that's what I do all the time) you have to create a Read/Write rules file which instructs FrameMaker what elements are table elements. In bothe cases your XML after preprocessing must contain an attribute at table level specifying the number of columns in the table.
- Michael
Copy link to clipboard
Copied
Zeb,
You have to edit your XSL so that it creates an XML file that mimics the structures allowed in your FrameMaker EDD, not HTML (unless your EDD mimics an HTML document).
Then you need to create read/write rules to help FrameMaker translate your XML structures (the structures created from the XSL processing) into FrameMaker table objects. See the Structured Applications guide that ships with FrameMaker. The rules I use are:
element "Table" {
is fm table element;
attribute "columns" is fm property columns;
attribute "columnwidths" is fm property column widths;
attribute "tableformat" is fm property table format;
}
element "TableTitle" is fm table title element;
element "TableHeading" is fm table heading element;
element "TableBody" is fm table body element;
element "Row" is fm table row element;
element "Cell" is fm table cell element;
The element names at the beginning of each line are the names used in the XML that results from the XSL. At the end of each line, you need to add the name of the corresponding element in your EDD. So, for example, the last line might look like this:
element "td" is fm table cell element "entry";
This assumes your XSL-processed XML uses td elements for table cells and your FrameMaker EDD uses entry elements for table cells.
Hope this helps,
Van
Copy link to clipboard
Copied
Hi Michael, Van,
Thank you for responding to my post. Your feedback was very helpful!
I was able to get the table to generate in FrameMaker but no data from the XML file is flowing into it. All that appears is the header row with "Title," "Number," and "Date" in the cells, and a row with blank cells underneath it. The Structure View pane has a red "<no value>" for the "Cols" and "Widths" attributes of the Table element. Only the Title column is affected by the width value.
The XSL, RW, and EDD files are as a follows: (The structure for the XML is a "Products" root element with mulitple "Product" child elements that each have a "Title," "Name," "Date" child element.)
==========================XSL==================
<xsl:stylesheet version='1.0' xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" doctype-system="products_DTD3.dtd" />
<xsl:template match="/">
<products>
<Table cols="3" width="150">
<TableHeading>
<TableRow>
<TableCell>Title</TableCell>
<TableCell>Number</TableCell>
<TableCell>Date</TableCell>
</TableRow>
</TableHeading>
<TableBody>
<TableRow>
<TableCell><xsl:for-each select="Products/Product"><xsl:value-of select="Title"/></xsl:for-each></TableCell>
<TableCell><xsl:for-each select="Products/Product"><xsl:value-of select="Number"/></xsl:for-each></TableCell>
<TableCell><xsl:for-each select="Products/Product"><xsl:value-of select="Date"/></xsl:for-each></TableCell>
</TableRow>
</TableBody>
</Table>
</products>
</xsl:template>
</xsl:stylesheet>
==========================EDD==================
Element (Container): products
General rule: Table
Valid as the highest-level element.
Element (Table): Table
General rule: TableHeading,TableBody
Attribute list
Name: cols String Required
Name: width String Required
Element (Table Heading): TableHeading
General rule: TableRow
Element (Table Row): TableRow
General rule: TableCell+
Element (Table Cell): TableCell
General rule: <TEXT>
Element (Table Body): TableBody
General rule: TableRow
==========================RW===================
fm version is "10.0";
element "Table" {
is fm table element;
attribute "cols" is fm property columns;
attribute "width" is fm property column widths;
}
element "TableRow" is fm table row element;
element "TableHeading" is fm table heading element;
element "TableBody" is fm table body element;
element "TableCell" is fm table cell element;
===============================================
I'm having trouble placing the "<xsl:for-each select="Products/Product">" tag in the XSL file. When I put it under TRow, FrameMaker gives an error that "TRow is not a valid for content (TCell)+". Only when I place it within the TCell tags (as I have above) does the above-mentioned Table with a Header row and a row with empty cells generate.
Is the XSL the problem here?
Thanks,
Zeb
Copy link to clipboard
Copied
Zeb,
Your XSL is incorrect.
<Table cols="3" width="150">
<TableHeading>
<TableRow>
<TableCell>Title</TableCell>
<TableCell>Number</TableCell>
<TableCell>Date</TableCell>
</TableRow>
</TableHeading>
<TableBody>
<xsl:for-each select="Products/Product">
<TableRow>
<TableCell><xsl:value-of select="Title"/></TableCell>
<TableCell><xsl:value-of select="Number"/></TableCell>
<TableCell><xsl:value-of select="Date"/></TableCell>
</TableRow>
</xsl:for-each>
</TableBody>
</Table>
You want to create a row FOR EACH product. So, the for-each element interates over the Product elements in the XML, creates a row for each product, inserts a cell for each field in the Product, and then inserts the field value into the cell.
Regards,
Van

