Introduction to Xstl with Delphi

xiaoxiao2021-03-06  112

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:

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:

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:

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 statement to make Sure the resulting XML Document Is The Same Format As The Input XML Document:

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:

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:

>

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:

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:

This XSL Transformation template above is especially designed to handle data packets that are coming from the XMLBroker component, and can originally be found in the XSLProducer WebSnap demo directory of Delphi 6 itself Tip:. If for some reason you can not locate this example, then you can use Delphi 6 to produce it for you as example template Do File |. New |. Other, go to the WebSnap tab of the Object Repository and double-click on the WebSnap Page Module icon In the dialog that follows, select XSLPageProducer as Producer type. Now, make sure the XSL "New File" option is checked, and select the type of template from the combobox (standard, blank or data packet). For our example, select "data packet". Ignore all other options on the dialog, because we are only interested in the generated XSL template file. Click on OK to generate a new WebSnap Page Module. Click on the new Uni1.xsl tab, copy the contents and paste it inside the XML property of the XSLPageProducer. Alternately, You May S ave the contents in file datapacket.xsl and assign the FileName property to datapacket.xsl (note that the property editor starts to look for .xml files first, you need to make sure to put the .xsl file inside it). Make sure that you do not save the Unit1.pas or .dfm itself, since we now need to remove the useless WebSnap Page Module from the WebBroker project. (do View | Project Manager, and remove Unit1 from the WebBroker project) and finally, in case You're Intested, The Standard XSL Template Produces The Following Three Lines (Ready for You To Enter Your Own Custom XSL):

And The Blank XSL Template Is Indeed Just An Empty File.

The best thing, however, is that we can use the XSLPageProducer in a "normal" WebBroker environment, without the need for WebSnap Page Modules. The XSL Template language using XPath and XPointer can be used to specify the transformation from XML to HTML-compliant Xml That Can Be Shown in The Browser.

XSLT ProcessorIn order to build our own XSLT Processor, we need an XMLDocument component (filled with an XML Document), as well as a place to store the XSLT templates, and a place to store the resulting transformation. Figure 1 shows a Delphi form at Design-Time With Three Memo Fields: Memoxml, Memoxslt and Memoxsl (for the result) AS Well as a xsmldocument and xslpageproducer component to perform the work.

The Few Steps of Code That Are Needed to Perform The Xslt Transformation Area Follows:

Try

XmlDocument1.active: = false; // Just in Case

XslpageProducer1.FileName: = filenamexslt;

XmLDocument1.FileName: = filenamexml;

XslpageProducer1.xmldata: = xmldocument1;

XmlDocument1.active: = true;

Memoxsl.text: = xslpageproducer1.content; // Transform !!

XMLDocument1.act: = false;

Except

ON E: Exception DO

Memoxsl.Text: = E.MESSAGE

END;

Alternative ApproachIf you do not have Delphi 6 or 7 Enterprise, then you do not have WebSnap with the XSLPageProducer component. Fortunately, there's still a way to perform the same XSLT Transformation using the transformNode method of the IXMLDOMDocument interface (from the MSXML unit ):

Procedure TFORM1.XSLT1Click (Sender: TOBJECT);

Function loadXmldoc (const filename: wideString): ixmldomdocument;

Begin

Result: = CoDomDocument.create ();

Result.async: = false; result.load (filename);

// olecheck (result.parseerror.errorcode);

END;

VAR

DOC, XSL: IXmldomDocument;

Begin

Try

Doc: = loadingXMLDoc (XML);

XSL: = loadingXMLDoc (xslt);

Memoxsl.text: = doc.transformnode (xsl)

Except

ON E: Exception DO

Memoxsl.Text: = E.MESSAGE

end

END;

As final example, remember the input.xml file (including attributes) that was transformed to output.xml (attributes changed into elements) by the Attr2Child.xslt transformation, which is shown in action in the figure below:

Xslt on .NetWe Can Also Perform Xslt Transformations (To Work On XML Documents) on the .net framework using the system.xml.xsl and system.xml.path names from the system.xml assembly.

Program xslt;

{$ Apptype console}

Uses

System.io,

SYSTEM.XML,

SYSTEM.XML.XSL,

System.xml.xpath;

VAR

Xsltrans: xsltransform;

Xmldoc: xmldocument;

XMlout: XmlReader;

XMLStream: filestream;

Begin

Try

Xsltrans: = xsltransform.create;

XSLTRANS.LOAD ('attr2child.xslt');

Xmldoc: = xmldocument.create;

XMLDoc.Load ('Input.xml');

{Xmlout: = xsltrans.transform (xmldoc, nil);

Xmlout.Free;

} XmlStream: = system.io.filestream.create ('output.xml', filemode.create);

XSLTRANS.TRANSFORM (XMLDoc, NIL, XMLStream);

Xmlstream.flush;

Except

ON E: Exception DO

Writeln (E.CLASSNAME, ':', E.MESSAGE)

END;

XMLStream.free;

XMLDoc.free;

Xsltrans.Free;

End.

This simple example shows that we can use the Transform method of the XslTransform class to transform a XmlDocument and produce a XmlReader (or directly write the output to an XML FileStream). This code should be enough basis to get you started to write more extensive XSTL processing applications for .NET.SummaryIn this paper, I have give an introduction to the basic capabilities of XSLT, although everyone should conclude for his or herself if XSLT can be beneficial. I do not use it very often, but when I do, I'm glad it's around (and support by Delphi). I've also shown how we can use the msxsl command-line XSLT processor, and how we can build at least three different XSLT processors using Delphi 7 and the Delphi for .NET Preview Command-Line Compiler or delphi 8 for .net.

转载请注明原文地址:https://www.9cbs.com/read-101535.html

New Post(0)
CopyRight © 2020 All Rights Reserved
Processed: 0.036, SQL: 9