views:

801

answers:

4
+2  A: 

Internet Explorer is surely using the MSXML library. Set the TXmlDocument.DomVendor property to MSXML_DOM (found in the msxmldom unit), and you should get the same behavior. You can also change the DefaultDOMVendor global variable to SMSXML to make all new TXmlDocument objects use that vendor.

Rob Kennedy
Thanks Rob, your answer is helpful but it doesn't solve my problem. I expect to get the same results as using Internet Explorer with MSXML_DOM but that's not the case. The parser still doesn't include the referenced file. I tried the other parsers available in Delphi without success.
Tihauan
+1  A: 

Have you already tried OmniXML? I've been using it for years and it always solved my problems regarding XML files. If you haven't, I'd advice you to give it a try: it's simple to use, light and free.

SoftwareSculptor
+1  A: 

Internet Explorer use XmlResolver, The XmlResolver property of the XmlDocument is used by the XmlDocument class to locate resources that are not inline in the XML data, such as external document type definitions (DTDs), entities, and schemas. These items can be located on a network or on a local drive, and are identifiable by a Uniform Resource Identifier (URI). This allows the XmlDocument to resolve EntityReference nodes that are present in the document and validate the document according to the external DTD or schema.

you should use a delphi library that implements a resolver and parser to external resources.

Open XML implements a resolver using TStandardResourceResolver

Bye.

RRUZ
The default parser has a property called "ParseOptions" and setting it to "poResolveExternals" makes it look for external references (if the files are not found I get an error). However the placeholders are not replaced with the external content. Any idea on how can I make the parser also replace the content? I think that would solve my problem.
Tihauan
Hi Tihauan, please post your code to help you.
RRUZ
+1  A: 

The following solved the problem for me. It seems that Delphi default parser (MSXML) actually includes external entity references but in a somehow strange way. For this example

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module [
<!ENTITY Schema65 SYSTEM "schemas/65.xml">
]>
<module>
  <schema>&Schema65;</schema>
</module>

I assumed that creating an TXMLDocument and that the external file contains a simple text I could get the contents of the file like this:

MyXML := TXMLDOcument.Create(myfile.xml);
ExternalText := MyXML.documentElement.ChildNodes['schema'].Text;

This actually works if the entity reference is replaced with the simple text. However, in case of using the external entity Delphi will create a new child of type "ntEntityRef" inside the "schema" node. This node will also have a child which finally contains the simple text I expected. The text can be accesses like this:

MyXML.documentElement.ChildNodes['schema'].FirstChild.FirstChild.Text;

In case the external entity file contains a node structure, the corresponding nodes will be created inside the entity reference node. Make sure TXMLDocument.ParseOptions are set to at least to [poResolveExternals] for that to happen. This approach also makes it relatively easy to adapt the code generated by the XML Data Binding Wizard to work with external entities.

Tihauan