Reading an XML Document While Resolving External Entities

This topic illustrates how to implement an XmlLite application that reads an XML document with external entities. This sample includes the following files:

This sample provides a custom external entity resolver that replaces an entity (&date;) with the current date. Note that this sample does not illustrate how to resolve external entities that refer to other URIs on other domains.

If a custom external entity resolver is not implemented correctly, cross domain/zone attacks can be introduced. For more information about XmlLite security, see XmlLite Security.

To create the example

  1. Create a Visual Studio 2005 project. For more information about how to create an XmlLite application, see Building XmlLite Applications.

  2. Copy the content of Source: XmlLiteReadExternalEntities.cpp into your C++ source file.

  3. Build the example. This creates the debug directory that is required in the next step.

  4. Create an XML document with Visual Studio 2005 or your favorite editor and copy the content of Source: date.xml into this XML document. Copy the document to the debug directory.

  5. Run the sample and verify that the output matches the output provided in Output from XmlLiteReadExternalEntities.

The following is the detailed list of what you have to do to implement an XmlLite application that reads an XML document with external entities:

  • Implement a class that extends the IXmlResolver interface. You should implement IXmlResolver to give the reader control over resolving external entities in XML. IXmlResolver contains the ResolveUri method that is called by the reader for each external entity in the input. If the ResolveUri method is implemented improperly, cross domain/zone attacks might be introduced.

  • Create an instance of the class that implements the IXmlResolver interface:

    DateXmlResolver* pXMLResolver = new DateXmlResolver();
    
  • Use the IxmlReader.SetProperty method to configure the reader to allow the use of Document Type Definitions (DTDs). This is required because the date.xml file contains a DTD element that defines the external entity. The following example illustrates how to set the XmlReaderProperty_DtdProcessing property:

    if (FAILED(hr = pReader->SetProperty( XmlReaderProperty_DtdProcessing, DtdProcessing_Parse)))
    {
        wprintf(L" Error setting XmlReaderProperty_DtdProcessing, error is %08.8lx", hr);
        return -1;
    }
    
  • Use the IXmlReader.SetProperty method to set pXMLResolver for the reader. The reader calls the ResolveUri method of the DateXmlResolver for each external entity in the input. If this property is not set, the reader simply replaces external entities with an empty string. The following example illustrates how to set the XmlReaderProperty_XmlResolver property:

    if (FAILED(hr = pReader->SetProperty(XmlReaderProperty_XmlResolver, (LONG_PTR)pXMLResolver)))
    {
        wprintf(L" Error setting XmlReaderProperty_XmlResolver, error is %08.8lx", hr);
        return -1;
    }
    
  • From this point, every time the reader comes across an external entity it calls the ResolveUri method of the DateXmlResolver to get the content of that entity.

  • When you are done using pXMLResolver, release it:

    pXMLReslover->Release();
    
Show: