This demo is intended to show you how you can fill a list with all of the available parsers. In addition it shows the basics of checking the features of an XMLReader. This demo does not include any information about parsing. For more information about parsing, please see the Simple Parsing Demo.
In order to fill the list with parsers you must first make sure that there are available parsers within your project. To do this, you must add the files to the Project. (The technical reasons behind this are simple, the initialization code for each parser package must be called. By adding the unit to the project you can be sure that the project will execute the code in the package's initialization section)
First click "Project | Add To Project
" on the
file menu. In this demo you should see that SAXKW and SAXMS
have already been added for you. This allows you to use
either of the default parsers provided by Keith Wood. You
can add another parser by including the unit that declares
that package's vendor information.
Now that you have some available SAX parsers you will want
to add some code to fill a list. In this demo our list is a
TComboBox string list. We will need to include the SAX
unit in the uses clause. Then we can just add the code to the FormCreate.
First we fill the list, then we select the DefaultSAXVendor.
// Fill the list ListSAXVendors(ComboBox1.Items); // Set the item index ComboBox1.ItemIndex:= ComboBox1.Items.IndexOf(DefaultSAXVendor);
Remember the DefaultSAXVendor is a SAXString so we must look it up by it's index in the ComboBox rather than simply setting the ItemIndex.
Now that we have code to fill the list with the available parsers, we
will add an OnChange
event to the our TComboBox so that
we can see the features of each parser's XMLReader. This demo
shows which features are turned on by default. If a specific feature
is not supported it will show "Not Supported". Checking certain features
may not be supported at different times (e.g. when parsing or
when not parsing) but may be supported at other times.
It is important to be aware that in SAX for Pascal there are two kinds of Vendors: Normal and Buffered. A Buffered Vendor is a vendor that is relying on the Buffered (or PSAXChar) versions of the interfaces, such as IBufferedXMLReader. Generally these parsers are much faster because they require fewer string allocations. A good example of a Buffered SAX vendor is KDSSAXExpat.
We begin by adding the event, then we will try to get information about the Vendor and XMLReader itself. Essentially we must begin by getting the Vendor and accessing the Description or XMLReader:
// Get the vendor AVendor:= GetSAXVendor(ComboBox1.Items[ComboBox1.ItemIndex]); // Get the description labDesc.Caption:= AVendor.Description; // Get the XML Reader Buffered:= AVendor is TBufferedSAXVendor; if Buffered then AXMLReader:= TBufferedSAXVendor(AVendor).BufferedXMLReader else AXMLReader:= AVendor.XMLReader;
Again, we are checking what kind of Vendor we have. If it is a
TBufferedXMLReader, we will access the BufferedXMLReader property.
Once we have the XMLReader we can check its features. We must be careful
however if a feature is not recognized the XMLReader will raise an
ESAXNotRecognizedException
. In some cases a checking property
might not be supported when parsing or when not parsing. If checking
a feature (or setting a feature) is not supported at a given time
the XMLReader will raise an ESAXNotSupportedException
exception.
Because of this, it is safest to wrap this code in a try..except
block:
try // Check for the feature if GetFeature(ValidationFeature, AXMLReader, Buffered) then labVal.Caption:= 'Yes' else labVal.Caption:= 'No'; except on e : ESAXNotRecognizedException do begin // The XMLReader didn't recognize the feature labVal.Caption:= 'Not recognized' end; on e2 : ESAXNotSupportedException do begin // The XMLReader doesn't support querying this feature right now labVal.Caption:= 'Not supported' end; end;
This will keep the exception from showing in the application. Instead it will only show when you are debugging the application in Delphi. You can also set features this way. Again, you need to be careful that the feature is recognized and supported.
Notice that we used the function GetFeature. You may be wondering what that function does. All it does is provide an easy way to check the feature of either a normal or Buffered XMLReader:
function GetFeature(Feature: SAXString; XMLReader: IUnknown; Buffered: Boolean): Boolean; begin if Buffered then Result:= IBufferedXMLReader(XMLReader).Features[Feature] else Result:= IXMLReader(XMLReader).Features[Feature]; end;
Features in SAX are identified by URLs. However, this does not mean that you can type a feature URL in the browser and look it up. They are simply used as unique identifiers. This demo shows all of the basic features but others may be used by specific vendors.