I have an XML file and an XSLT and I want to use the XSLT to trasform the XML into an HTML string which could be loaded into a TWebBrowser
.
For my tests, I'm using these example files.
XML File:
<?xml version="1.0" encoding="UTF-8"?>
<breakfast_menu>
<food>
<name>Belgian Waffles</name>
<price>$5.95</price>
<description>Two of our famous Belgian Waffles with plenty of real maple syrup</description>
<calories>650</calories>
</food>
<food>
<name>Strawberry Belgian Waffles</name>
<price>$7.95</price>
<description>Light Belgian waffles covered with strawberries and whipped cream</description>
<calories>900</calories>
</food>
<food>
<name>Berry-Berry Belgian Waffles</name>
<price>$8.95</price>
<description>Light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>
<calories>900</calories>
</food>
<food>
<name>French Toast</name>
<price>$4.50</price>
<description>Thick slices made from our homemade sourdough bread</description>
<calories>600</calories>
</food>
<food>
<name>Homestyle Breakfast</name>
<price>$6.95</price>
<description>Two eggs, bacon or sausage, toast, and our ever-popular hash browns</description>
<calories>950</calories>
</food>
</breakfast_menu>
XSLT File:
<?xml version="1.0" encoding="UTF-8"?>
<html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
<xsl:for-each select="breakfast_menu/food">
<div style="background-color:teal;color:white;padding:4px">
<span style="font-weight:bold"><xsl:value-of select="name"/> - </span>
<xsl:value-of select="price"/>
</div>
<div style="margin-left:20px;margin-bottom:1em;font-size:10pt">
<p>
<xsl:value-of select="description"/>
<span style="font-style:italic"> (<xsl:value-of select="calories"/> calories per serving)</span>
</p>
</div>
</xsl:for-each>
</body>
</html>
Attempt 1:
I've found this solution and tried the function:
Uses
XMLDoc, XMLIntf;
function Transform(XMLContent : string; XSLContent : string) : WideString;
var
XML : IXMLDocument;
XSL : IXMLDocument;
begin
XML := LoadXMLData(XMLContent);
XSL := LoadXMLData(XSLContent);
XML.DocumentElement.TransformNode(XSL.DocumentElement, Result)
end;
But it produces an unexpected output:
Belgian Waffles$5.95Two of our famous Belgian Waffles with plenty of real maple syrup650Strawberry Belgian Waffles$7.95Light Belgian waffles covered with strawberries and whipped cream900Berry-Berry Belgian Waffles$8.95Light Belgian waffles covered with an assortment of fresh berries and whipped cream900French Toast$4.50Thick slices made from our homemade sourdough bread600Homestyle Breakfast$6.95Two eggs, bacon or sausage, toast, and our ever-popular hash browns950
Attempt 2:
I've found the following function in the "Using the MSXML Parser/ Transform Engine" section of this page (Note: it's a Delphi 5 example but I'm using Delphi 2007).
function DoTransform(const xml, xsl : string ): string;
var
XMLDoc : IXMLDOMDocument;
XSLDoc : IXMLDOMDocument;
Template : IXSLTemplate;
Processor : IXSLProcessor;
begin
Result := '';
try
XMLDoc := CoFreeThreadedDOMDocument30.Create;
XSLDoc := CoFreeThreadedDOMDocument30.Create;
XMLDoc.load(xml);
XSLDoc.load(xsl);
Template := CoXSLTemplate30.Create;
Template.stylesheet := XSLDoc;
Processor := Template.createProcessor;
Processor.input := XMLDoc;
Processor.transform;
result := Processor.output;
finally
XMLDoc := nil;
XSLDoc := nil;
end;
end;
I've imported the Microsoft XML type library...
Component -> Import Component -> Import a Type Library -> Next -> Microsoft XML, v6.0
...and added MSXML2_TLB
to the uses clause but then some other errors occours:
E2003 Undeclared identifier: 'CoFreeThreadedDOMDocument30'
E2003 Undeclared identifier: 'CoXSLTemplate30'
I've switched CoFreeThreadedDOMDocument30
to CoFreeThreadedDOMDocument60
and CoXSLTemplate30
to CoXSLTemplate60
and now it compiles without errors.
At runtime, at this line:
Template.stylesheet := XSLDoc;
It raises the following exception (In italian):
Il foglio di stile non include un elemento documento. Il foglio di stile รจ vuoto oppure potrebbe essere un documento XML in formato non corretto.
In english it should be something like this:
The stylesheet doesn't include a document element. The stylesheet is empty or it could be a bad formatted XML document.
I've tested with other example files and the error is always the same and I don't understand which could be the problem.
Am I on the right way or are there better ways to do what I need?