How Can I Load a document when I Don't know what's in it?

Problem

Depending on how you set your system up, it is possible that you receive an XML document, not knowing what it contains. For Example if your writing a service that can process a number of different requests. Each different request may be represented by a different XML element. So the service handling the requests would not know what they contained until its opened them.

Simple Example

<xsd:element name = "StatementRequest"> ... <xsd:element name = "BalanceRequest"> ...

Sample Document

<?xml version = "1.0" encoding = "UTF-8"?> <StatementRequest> ...

Resolution

Load the Document Dynamically

Because we don't know the type of document we are dealing with, we have to load it and have a 'peek' at it. We can then create the appropriate type of object, and load the data into it. When we re-load the data we take care not to re-parse the document (saving processing and memory overhead).

  C++

Sample Document

try { // load the document using the XML parser that comes with Liquid XML LtXmlLib16::CXmlDocument XmlDoc; XmlDoc.Load(strFullPath.c_str()); // Now use the class factory to create the object using the root element in the docuemnt as a guide LtXmlLib16::CXmlObjectBasePtr spObj = tns::CClassFactory::IDocumentCreateObject(XmlDoc.GetDocumentElement()).Ptr(); // Now read the document into the new object spObj->FromXmlFile(strFullPath.c_str()); // Check the actual type of the root element std::tstring typeName = XmlDoc.GetDocumentElement()->GetAttribute(_T("type"), _T("http://www.w3.org/2001/XMLSchema-instance")); if (typeName == _T("RequestTradeConfirmation")) { // cast the spObj to specific type tns::CRequestTradeConfirmationPtr spRequestTradeConfirmation = dynamic_cast<tns::CRequestTradeConfirmation*>(spObj.Ptr()); std::tstring strXML = spRequestTradeConfirmation->ToXml(); _tprintf(strXML.c_str()); } } catch (CLtException& ex) { _tprintf(_T("FAILED - to validate %s\nError %s\n"), lpctFilename, ex.GetFullMessage().c_str()); }

  C#

Sample Document

try { // use the standard .Net XML document to load the XML System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument(); xmlDoc.Load(filename); // Now examine the root element and create the correct type of object if (xmlDoc.DocumentElement.LocalName == "StatementRequest") { StatementRequest stmtRq = new StatementRequest(); stmtRq.FromXmlElement(xmlDoc.DocumentElement); MyStatementRequestHandler(stmtRq); } else if (xmlDoc.DocumentElement.LocalName == "BalanceRequest") { BalanceRequest balRq = new BalanceRequest(); balRq.FromXmlElement(xmlDoc.DocumentElement); MyBalanceRequestHandler(balRq); } else { // Error Unknown XML document } } catch (Exception e) { // Note : exceptions are likely to contain inner exceptions // that provide further detail about the error. while (e != null) { Console.WriteLine("Error - " + e.Message); e = e.InnerException; } }

  Java

Sample Document

try { // load the document using the XML parser that comes with Liquid XML com.liquid_technologies.ltxmllib16.dom.XmlDocument parser = new com.liquid_technologies.ltxmllib16.dom.XmlDocument(); parser.parse(filename); // Now examine the root element and create the correct type of object if (xmlDoc.getDocumentElement().getLocalName().equals("StatementRequest")) { StatementRequest stmtRq = new StatementRequest(); stmtRq.fromXmlElement(xmlDoc.getDocumentElement()); MyStatementRequestHandler(stmtRq); } else if (xmlDoc.getDocumentElement().getLocalName().equals("BalanceRequest")) { BalanceRequest balRq = new BalanceRequest(); balRq.fromXmlElement(xmlDoc.getDocumentElement()); MyBalanceRequestHandler(balRq); } else { // Error Unknown XML document } } catch (Throwable e) { // Note : exceptions are likely to contain inner exceptions // that provide further detail about the error. System.out.println("OK - Successfully failed to load an invalid file " + filename); while (e != null) { System.out.println("Error " + e.getMessage()); e = e.getCause(); } }

  Visual Basic

Sample Document

Dim elm As IDocument Dim oCF As New Sample.ClassFactory Dim oMsXML As New MSXML2.DOMDocument ' Because the initial element is abstract ' we need to create it using the ClassFactory method IRequestTypeCreateObject oMsXML.Load strFilename ' Now examine the root element and create the correct type of object if xmlDoc.DocumentElement.LocalName = "StatementRequest" Then Dim oStmtRq As new StatementRequest stmtRq.FromXmlFile strFilename MyStatementRequestHandler(stmtRq); ElseIf xmlDoc.DocumentElement.LocalName = "BalanceRequest" Then Dim oBalRq As new BalanceRequest oBalRq.FromXmlFile strFilename MyBalanceRequestHandler oBalRq Else ' Error Unknown XML document End If

 

Notes

Description Value
Article Created 6/2/2006
Versions Liquid XML 2005 (4.2.0) and greater