The Microsoft XML library (MSXML) is a set of COM objects for using XML
and XSL. MSXML is available for download from Microsoft's
XML site.
It is easiest to use these COM libraries if you create a seperate library
to store the Dylan wrappers that call the COM routines. Functional Developer
includes a wizard that makes this easy but it has a problem with importing
the MSXML library which is easily fixed.
The steps to get a working Dylan wrapper to MSXML are:
- Install the March 2000 preview release of MSXML from the Microsoft
XML site. Install the XML SDK if you want the XML documentation
(Definitely recommended).
- Start a new Dylan project using "Interface to COM Type Library"
as the wizard.
- From the list of type libraries choose "Microsoft XML, v3.0".
- The stub option from the next wizard page should be the first one,
"Dispatch client interfaces".
- The next page allows you to select individual interfaces to include
in the translation. Functional Developer 2.0 has a problem generating
code for one of the items in the list. To prevent this problem, select
the "Translate Selected" option and select everything in the
list except for the very last item called "XML Document" (An
easy way to do this is to select the one above "XML Document"
called "__xml_error" and press Shift+Home).
- On the next page, choose any name for the project that you want. In
this example I use "example-msxml".
- The following page allows you to select additional libraries. Choose
"Minimal".
- Choose Finish from the last page and you'll have a project. One change
needs to be made to the project to prevent a compilation warning.
- Edit the file
module.dylan and remove the following lines:
use simple-format;
use threads;
- Compile the project. It should compile successfully.
The next stage is to create a project that uses the library we built
above. In the example below we'll create a project and use the interactor
to play with the MSXML library interactively.
- Start a new project. Use the "Console Application" wizard.
You can use the GUI Application Wizard as well but the console one keeps
things simple for this example.
- In the "User Libraries" page of the wizard, choose "Minimal"
and press Finish on the following page. The project should be created.
- Edit
library.dylan and add the library we created for
the MSXML wrappers and the ole-automation library. Something
like:
define library xml-play-1
use functional-dylan;
use ole-automation;
use example-msxml;
export xml-play-1;
end library xml-play-1;
Note that I called the project xml-play-1 .
- Edit
module.dylan and add the module for the MSXML wrapper
library and the ole-automation module. Something like:
define module xml-play-1
use functional-dylan;
use simple-format;
use ole-automation;
use example-msxml;
end module xml-play-1;
- Compile the project using "Interactive Development Mode"
(This can be set from the Projects/Settings menu option in the project).
You now have a compiled project that you can use to interactively experiment
with the MSXML library. Here is an example of using it:
Choose "Application/Interact" from the menu of the project
you just created.
You are now at the interactor prompt and can enter Dylan expressions.
This is useful for exploring libraries and trying out ideas while
writing programs. It is similar in functionality to a Lisp listener.
In the following, anything appearing after '=> ' is
the result displayed by the interactor. Don't enter this, the interactor
will display it.
- The first method to call is to initialize the OLE libraries. Enter:
ole-initialize();
=> no values
- Create an XML DOM document object:
make(<IXMLDOMDocument>, class-id: "Microsoft.XMLDOM");
=> $0 = {<ixmldomdocument>}
- Load some XML:
IXMLDOMDocument/loadXML($0,
"<test><line>Line 1</line><line>Line 2</line></test>");
=> $1 = #t
The '#t ' indicates that the load succeeded.
- We can get the root of the DOM tree:
IXMLDOMDocument/documentElement($0);
=> $2 = {<ixmldomelement>}
- If you want to know what methods you can call on an object (say, the
$2 that was returned above) you can right click on the
<ixmldomelement> on the $2 line and
choose "Browse Type" from the menu. A browser will appear
showing all the methods (and other things) for that type. This is a
great way to interact, experiment and otherwise explore with the XML
libraries. Continuing the iteration through the DOM tree:
IXMLDOMElement/childNodes($2);
=> $3 = {<ixmldomnodelist>}
IXMLDOMNodeList/Length($3);
=> $4 = 2
as(<byte-string>, IXMLDomNode/text($3[0]));
=> $6 = "Line 1"
as(<byte-string>, IXMLDomNode/text($3[1]));
=> $7 = "Line 2"
- Here is an example of all the above used to print the XML nodes to
the console:
with-interface(dom = make(<IXMLDOMDocument>,
class-id: "Microsoft.XMLDOM"))
IXMLDOMDocument/loadXML(dom,
"<test><line>Line 1</line><line>Line 2</line></test>");
with-interface(root = IXMLDOMDocument/documentElement(dom))
with-interface(child-nodes = IXMLDOMElement/childNodes(root))
for(index from 0 below IXMLDOMNodeList/Length(child-nodes))
format-out("%s\n",
as(<byte-string>, IXMLDOMNode/text(child-nodes[index])))
end for
end
end
end;
The above uses the with-interface macro which I created
to automatically call release on the COM interfaces:
define macro with-interface
{ with-interface ( ?:name = ?init:expression ) ?:body end }
=> { begin
let ?name = ?init;
block()
?body
cleanup
release(?name)
end
end
}
end macro with-interface;
The default wrappers that are created are quite verbose to use. It is
possible to make the MSXML library easier to use and read by using some
of the more advanced options that can be passed to the OLE wrapper macros.
But the above examples should give a good starting to exploring OLE and
XML with Dylan. An interesting exercise would be to come up with a more
Dylan style XML framework. Perhaps implemented using the automatically
generated MSXML wrappers.
|