Reasons to Use XML Data Binding
| |
- Reduces Development Time
- Increased reliability (spot problems at compile time not runtime)
- Creates more readable code
- Fastest root between code and XML
|
|
Reasons To Use Liquid XML Data Binding Code Generator
| |
|
- Compiles on Linux.
- Includes runtimes for gcc
3.2, 3.2.2 & 3.4.1,
4.0 (64bit)
- Runtime Source Code available which will compile on most compilers.
- Thread Safe
|
- Supports XSD, XDR & DTD's
- Generates simple intuitive code
- Supports the Fast Infoset XML compression
- Generates Documentation with the code.
- Royalty free distribution
|
|
Xml Data Binding
XML Data Binding allows you to treat your XML documents as objects within your application. This makes dealing with XML data from a programming language a simple matter of manipulating these strongly typed objects.
Liquid XML Data Binding Code Generator takes an XML Schema and uses it to generate a class library. These classes map directly to to data contained in your XML Schema, so if your schema has an Person entity and that has a date of birth attribute, then a class called Person will be generated, which will have a property called DateOfBirth. |
|
Standard Support
The use of XML is exploding, and with it the number and complexity of 3rd party standards. There are now 1000's of XML Schemas describing everything from Solar orbits to coffee bean quality. Because the XSD standard is complex, many XML Data Binding tools only support a sub set of it. This may be adequate for small in house schemas, but in the real world you need something that will cope with the standards that exist out in the wild. Liquid XML Data Binder has an unprecedented level of support for the W3C XSD Standard allowing it to cope with the most complex standards, just try it and see.
|
|
Tools Included with Liquid XML Studio
Liquid XML Data Binding Code Generator is included in the Developer Edition of Liquid XML Studio, which includes many other XML tools including
XSD Editor, XML Editor, XML Differencing tool, XPath Query viewer, Web Service Call Composer and more... see Liquid XML Studio.
|
 |
Platform Support
The C++ code is platform independent and has successfully been used on Windows, Linux, Solaris, HP-UX, Mac, embedded systems and other more obscure platforms.
Compiled Binary Libraries
- Win32
- Linux
- gcc 3.2.2, 3.2.2, 3.4.1, 4.2.4 (x86 32 bit) and 4.0.0 (x86 64 bit)
|
Un-modified C++ libraries compile on:-
- Win32/Win64
- Linux gcc
- Solaris
- Forte
|
The full C++ runtime source code is available (see Source Code License) and is easily compiled onto other platforms (e.g. HP-UX, Mac OS, embedded systems). |
|
Memory/Object Management
Memory Management is performed via reference counting, so no memory leaks. Smart Pointer classes are employed meaning you don't have to deal with any of the referencing counting. References are automatically released when your smart pointer goes out of scope.
Collections
Collections are strongly typed and use the stl iterator pattern.
Ease of Use
The generated classes expose the values in the XML as simple properties (getters & setters) allowing values to be easily manipulated. |
A Simple Example
The following example we will use the Person.xsd, shown below to demonstrate how to read and write an XML document based on this schema.
XML Schema - Bookstore.xsd - Click to View
Serializing the XML (Objects to XML) - Code to create an XML document using XML Data Binding Objects - Click to View
Using XML Data Binding |
Using the standard DOM approach |
CPersonPtr spPer = CPerson::CreateInstance();
spPer->SetName(_T("Fred"));
spPer->SetDateOfBirth(CDateTime(1978, 6, 26));
CAddressPtr spAddr = CAddress::CreateInstance();
spPer->SetAddress(spAddr);
spPer->GetAddress()->SetHouseNo(7);
spPer->GetAddress()->SetPostCode(_T("WV6 6JY"));
CCarPtr spRunAroundCar = CCar::CreateInstance();
spPer->GetCars()->Add(spRunAroundCar);
spRunAroundCar->SetModel(_T("Ford"));
spRunAroundCar->SetMake(_T("Escort"));
CCarPtr spToyCar = CCar::CreateInstance();
spPer->GetCars()->Add(spToyCar);
spToyCar->SetModel(_T("Lotus"));
spToyCar->SetMake(_T("Elise"));
printf(_T("XML = %s"), spPer->ToXml().c_str());
spPer->ToXmlFile(_T("SampleFile.xml"));
|
IXMLDOMDocument2Ptr spDoc;
spDoc.CreateInstance(__uuidof(DOMDocument40));
IXMLDOMElementPtr spElmPerson = spDoc->createElement(_T("Person"));
spDoc->appendChild(spElmPerson);
IXMLDOMElementPtr spElmName = spDoc->createElement(_T("Name"));
spElmPerson->appendChild(spElmName);
spElmName->text = _T("Fred");
IXMLDOMElementPtr spElmDOB = spDoc->createElement(_T("DateOfBirth"));
spElmPerson->appendChild(spElmDOB);
spElmDOB->text = _T("1978-06-26");
IXMLDOMElementPtr spElmAddress = spDoc->createElement(_T("Address"));
spElmPerson->appendChild(spElmAddress);
IXMLDOMElementPtr spElmHouseNo = spDoc->createElement(_T("HouseNo"));
spElmAddress->appendChild(spElmHouseNo);
spElmHouseNo->text = _T("7");
IXMLDOMElementPtr spElmPostCode = spDoc->createElement(_T("PostCode"));
spElmAddress->appendChild(spElmPostCode);
spElmPostCode->text = _T("WV6 6JY");
IXMLDOMElementPtr spElmCarRA = spDoc->createElement(_T("Car"));
spElmPerson->appendChild(spElmCarRA);
IXMLDOMElementPtr spElmRAModel = spDoc->createElement(_T("Model"));
spElmCarRA->appendChild(spElmRAModel);
spElmRAModel->text = _T("Ford");
IXMLDOMElementPtr spElmRAMake = spDoc->createElement(_T("Make"));
spElmCarRA->appendChild(spElmRAMake);
spElmRAMake->text = _T("Escort");
IXMLDOMElementPtr spElmCarToy = spDoc->createElement(_T("Car"));
spElmPerson->appendChild(spElmCarToy);
IXMLDOMElementPtr spElmToyModel = spDoc->createElement(_T("Model"));
spElmCarToy->appendChild(spElmToyModel);
spElmToyModel->text = _T("Lotus");
IXMLDOMElementPtr spElmToyMake = spDoc->createElement(_T("Make"));
spElmCarToy->appendChild(spElmToyMake);
spElmToyMake->text = "Elise";
wprintf(L"XML = %s", spDoc->xml.GetBSTR());
|
The XML Data Binding code is much easier to read, more concise and will allow errors to be detected at compile time should the data model change.
The DOM code is verbose, difficult to read, and should the data model change, the errors will only be picked up in testing. |
Deserializing the XML (XML to Objects) - Code to read an XML document using XML Data Binding Objects - Click to View
Using XML Data Binding |
Using the standard DOM approach |
CPersonPtr spPer = CPerson::CreateInstance();
// Load the XML
spPer->FromXmlFile(_T("SampleFile.xml"));
printf(_T("%s was born %s"),
spPer->GetName().c_str(),
spPer->GetDateOfBirth().ToString().c_str());
printf(_T(", and lives at %d, %s\n"),
spPer->GetAddress()->GetHouseNo(),
spPer->GetAddress()->GetPostCode().c_str());
printf(_T("Cars Owned (%d)\n"),
spPer->GetCars()->GetCount());
for (CCarCol::iterator itr =
spPer->GetCars()->begin();
itr != spPer->GetCars()->end();
itr++)
{
CCarPtr spCar = *itr;
printf(_T(" %s, %s\n"),
spCar->GetMake().c_str(),
spCar->GetModel().c_str());
}
|
IXMLDOMDocument2Ptr spDoc;
spDoc.CreateInstance(__uuidof(DOMDocument40));
spDoc->load(_T("SampleFile.xml"));
IXMLDOMElementPtr spElmPerson = GetFirstElement(spDoc);
if (spElmPerson == NULL || spElmPerson->nodeName != _bstr_t("Person"))
throw new CLtException(_T("Must start with Person"));
IXMLDOMElementPtr spElmName = GetFirstElement(spElmPerson);
if (spElmName == NULL || spElmName->nodeName != _bstr_t("Name"))
throw new CLtException(_T("Missing Person->Name"));
IXMLDOMElementPtr spElmDOB = GetNextElement(spElmName);
if (spElmDOB == NULL || spElmDOB->nodeName != _bstr_t("DateOfBirth"))
throw new CLtException(_T("Missing Person->DateOfBirth"));
IXMLDOMElementPtr spElmAddress = GetNextElement(spElmDOB);
if (spElmAddress == NULL || spElmAddress->nodeName != _bstr_t("Address"))
throw new CLtException(_T("Missing Person->Address"));
IXMLDOMElementPtr spElmHouseNo = GetFirstElement(spElmAddress);
if (spElmHouseNo == NULL || spElmHouseNo->nodeName != _bstr_t("HouseNo"))
throw new CLtException(_T("Missing Person->Address->HouseNo"));
IXMLDOMElementPtr spElmPostCode = GetNextElement(spElmHouseNo);
if (spElmPostCode==NULL||spElmPostCode->nodeName != _bstr_t("PostCode"))
throw new CLtException(_T("Missing Person->Address->PostCode"));
if (GetNextElement(spElmPostCode) != NULL)
throw new CLtException(_T("Unexpected Element found"));
wprintf(L"%s was born %s, and lives at %d, %s\n",
spElmName->text.GetBSTR(),
spElmDOB->text.GetBSTR(),
spElmHouseNo->text.GetBSTR(),
spElmPostCode->text.GetBSTR());
IXMLDOMElementPtr spElmCar = GetNextElement(spElmAddress);
while (spElmCar != NULL)
{
if (spElmCar->nodeName != _bstr_t("Car"))
throw new CLtException(_T("Unknown element "));
IXMLDOMElementPtr spElmMake = GetFirstElement(spElmCar);
if (spElmMake == NULL || spElmMake->nodeName != _bstr_t("Make"))
throw new CLtException(_T("Missing Person->Car->Make"));
IXMLDOMElementPtr spElmModel = GetNextElement(spElmMake);
if (spElmModel == NULL || spElmModel->nodeName != _bstr_t("Model"))
throw new CLtException(_T("Missing Person->Car->Model"));
if (GetNextElement(spElmModel) != NULL)
throw new CLtException(_T("Unexpected Element found"));
wprintf(L" %s, %s\n",
spElmMake->text.GetBSTR(),
spElmModel->text.GetBSTR());
spElmCar = GetNextElement(spElmCar);
}
IXMLDOMElementPtr GetNextElement(IXMLDOMNodePtr spXmlNode)
{
while (spXmlNode != NULL)
{
spXmlNode = spXmlNode->nextSibling;
IXMLDOMElementPtr spElm = spXmlNode;
if (spElm != NULL)
return spElm;
}
return NULL;
}
IXMLDOMElementPtr GetFirstElement(IXMLDOMNodePtr spXmlParent)
{
if (spXmlParent == NULL)
return NULL;
else if (spXmlParent->firstChild == NULL)
return NULL;
else
{
IXMLDOMElementPtr spElm = spXmlParent->firstChild;
if (spElm != NULL)
return spXmlParent->firstChild;
else
return GetNextElement(spXmlParent->firstChild);
}
}
|
| Because the XML Data Binding code does the bulk of the parsing fo you, manipulating the XML objects is just a matter of dealing with collections of objects, no need to continually check the type of an item etc. |
Conclusion
XML Data Binding makes it significantly easier to deal with XML documents from within your code, resulting in less code, which is simpler to read and maintain.
As the generated class library is strongly typed, it forms a kind of template for the developer, ensuring that the data created conforms the underlying XML Schema.
The maintenance phase of a project also befits as XML Data Binding allows any errors introduced because of changes in the data model to be caught early at compile time, unlike weekly typed DOM trees, which will give no indication of a problem until runtime. These kinds of changes can be a major cause of bugs which can only be caught in testing. Being able to identify these at compile time can save huge amounts of time and effort.
|