Introduction to XSTL with DelphiXSLT stands for eXtensible Stylesheet Language (XSL) Template, and is generally used to transform an XML document to another XML document (for example a HTML compliant XML document). In this article, I will give an introduction to the basic capabilities of XSLT, as well as the reasons why XSLT can be beneficial to Delphi developers. We'll start of with some simple examples of using XSTL to transform XML documents to other XML documents. We then move on to the XSLT support in Delphi in the form of the TXSLPageProducer component (found on the WebSnap tab, but actually not related to WebSnap at all), which can be used to convert any XML data packet or XML document (using XSL Transformation rules), but is not always clear in its Use. I will also show where to get a few xslt example That Are Also a bit "hidden" in Delphi 6 and 7 Enterprise.
Finally, I Will Show That Xslt on the .NET Framework Can Be Done Using The xsl classes from the system.xml.xsl namespace, Which Contains The Class Xsltransform for this purpose.
What is XSLT? XSLT stands for XSL Transformations, where XSL stands for eXtensible Stylesheet Language. It is primarily meant to transform XML documents to something else (another XML document, a HTML document or even a plain text document). Using Delphi (and Delphi for .NET), we can load XML documents, read them, work with them, but it's harder for perform the operations on XML documents that we can do with a few lines of XSTL. Besides, we can use Delphi to build an XSLT processor SO STILL Keep The "Main" Application in Delphi, While We're Using The xstl Capabilities of Win32 Or .NET.
How can you "run" XSLT? There are several ways to execute or apply an XSLT on a XML document. The easiest way is to download the msxsl.exe command-line tool from Microsoft at http://msdn.microsoft.com/ . xml msxsl.exe is a command-line XSLT processor, of which I use version 3. The instructions for running mSXSL are as follows: Usage: mSXSL source stylesheet [options] [param = value ...] [xmlns: prefix = Uri ...]
Options:
-? Show this message
-o filename Write Output to Named File
-m Startmode Start The Transform in this mode
-xw strip non-significant Whitespace from Source and Stylesheet
-xe do not resolve external definitions during parse Phase
-V Validate Documents During Parse Phase
-t show loading and transformation Timings
-pi get stylesheet url from xml-stylesheet pi in Source Document
-u Version Use a specific Version of MSXML: '2.6', '3.0', '4.0'
- Dash Used As Source Argument Loads XML from stdin
- Dash Used As Stylesheet Argument Loads XSL from Stdin
This will work fine as a blackbox for our first examples. However, later in this article we'll also build our own XSLT processors with both Delphi 7 (Enterprise) and Delphi for .NET (using the classes from the System.XML.XSL Namespace.
Some Examples of xltxslt itself is an xml document with a special syntax that we have to read to understand what it's doing. They start with the folload line (make no name ":
And Obviously End with:
xsl: stylesheet>
If you apply an otherwise empty XSLT document to an XML document, then no transformation are performed which means that all XML tags will be removed and only the text between the tags remains.A second XSLT example that ignores the XML document but simply produces some output Is the following:
clinics>
xsl: template>
xsl: stylesheet>
This ONE Uses An XSL: Output Statement That Specifies That The Output Is of Type XML (Version 1.0, UTF-8) AND That Indentation Should Be Done.
The XSL: Template Element Matches The Root of the Xml Document, WHERE The Transformation Starts, And Replace The root with the Litral Other Transformation Are Done.
Applying this Xslt Transformation On Any XML Document (Doesn't Matter Which One) Products The Following XML Output File:
XML Version = "1.0" encoding = "UTF-8"?>
clinics>
Now, suppose we want to change the attribute or a node from an XML document. We must then use another match expression, where a node is specified by the fully qualified name (starting from the root), and an attribute has an @ character before the name.The first example is to copy an XML document to itself - including the XML tags (each node to itself), which is defined as follows (note that I've ommited the
XSL: COPY>
xsl: template>
xsl: stylesheet>
The xsl: template element now matches the XPath expression node () which means each node in the XML document The xsl:. Apply-templates is used to replace the @ * with the XPath node () again which results in a literal copy of each INPUT Node to Itself as output note.
An Example That Extends this functionality and Turns Each Attribute Into a child node (element) is defined As Follows:
XSL: COPY>
xsl: template>
XSL: COPY>
xsl: template>
xsl: attribute>
xsl: for-energy>
XSL: COPY>
xsl: template>
xsl: stylesheet>
This consists of a number of steps. First of all, we start with the transformation of all nodes and attributes to themselves. Them the elements "file" are handled separately. We first copy the attributes of the file nodes themselves, and then for all sub-elements, turn them into attributes themselves. A problem could occur if this results into attributes with the same name (ie an element that also occured as attribute), but I leave it as excercise for the reader to decide how to rename the attributes In That Case.
Default TemplatesXSLT needs matching templates in order to perform the transformation. However, sometimes, no matching template can be found. For those casee, XSTL defines a number of default templates that will be used if no matching template can be found. The first default template Is Defined As Follows:
xsl: template>
This template matches all elements and the root, and continues the transformation process by re-applying the templates for the child elements (but not the attributes) of the current node. To ensure that all nodes are transformed.
Another Default Template Is Defined As Follows:
xsl: template>
This template matches the text nodes and all attributes from the elements and sends the values of these elements to the output. This is usually not what you would want, so you should try to transform text notes and attributes values yourself.
Our own XSLT ProcessorThere are several ways in which we can build our own XSLT Processor. I will start with Delphi 7 Enterprise, then move to Delphi Professional and show how we can perform the XSLT transformations by ourselves. In Delphi 7 Enterprise, we can find a rather strange component called the TXslPageProducer - as part of WebSnap (although it's not really tightly integrated with WebSnap to be honest) This component works like a regular PageProducer in that we can call the "Content" property to fire the method (the GetContent. That Will Perform The xslt transformation. The only problem is what of the profment That We can use to "feed" this Transformation Are Not Always clear ...
XML and XSLThe XSLPageProducer component can be used to turn an XML document (or XML string) into another XML string, using an EXtensible Stylesheet Language (XSL) template. Note that the Delphi 6 on-line help still calls it the TXMLPageProducer component instead of the TXSLPageProducer component. The XSLPageProducer component has a number of properties that can easily be confused with each other (like the FileName, XML and XMLData properties, as I will make clear in a moment). First of all, the only way to specify the input XML content is by using the XMLData property. You can not use the XML property, since this is used to specify the XSL template (just like the FileName is used to point to an external XSL template file). I wonder why the XML property isn 't called XSL, but I guess that's the same reason why the on-line help refers to it as the TXMLPageProducer instead the TXSLPageProducer component - it may have been renamed late in the development process of Delphi 6 (and Borland may have forgot the XML property - or would break existing code and examples by changing it) .XMLData propertyAnyway, the XMLData property can point to any component that implements the IXMLDocument interface (like the TXMLDocument component) or the IGetXMLStream interface (like the TXMLBroker component) . Since we're already using the data module with a TXMLBroker component, we can use that one. Just click on the XMLData property of the XSLPageProducer component and select XMLBroker1 to connect it to the XMLBroker component (which in turn connects to the XMLTransformProvider component ).
FileName propertyThe FileName property points to an external XSL template file, which should contain XSL Transformations (XSLT) using XPath and XPointer (a bit more about that in a moment). It may be handy to use the FileName property, but you can also use the XML property to make sure the XSL template is embedded within the XSLPageProducer component (and hence the web server application itself). Unfortunately, when you click on the ellipsis to start the property editor for the FileName property, you get a File Open dialog that by default starts to look for XML files. you have to open the "Files of type" combobox in order to specify that you're looking for XSL files instead.XML propertyThe XML property is yet another "strange one". you may think that this one can be used as alternative for the XMLData property, but that's not the case. The XML property is actually an alternative for the FileName property, and should in that function contain the XSL template, and not the XML data (so th e "XML" property is a bit misleading) Warning:.! if you click on the XML property and enter some XSL Transformations, be aware that you'll clear the FileName property It appears that the FileName and XML property are mutual exclusive If. you set a value to one, you clear the other. and this can be especially painful if you enter a new FileName property and accidentally clear the XML property (containing a potentially long list of XSL Transformations). In our example, I'll fill THE XML Property with The Following Set of XSL Transformations That Can Be Generated by Delphi Itself:
XML Version = "1.0"?>
body>
html>
xsl: template>