Use of  TXMLDocument component

Roger Alcindor
Roger Alcindor used Ask the Experts™
on
I need to generate an XML document based on the result of a database query (ADOQuery).
Is it appropriate to use a TXMLDocument component and if so how would I do this ?
I am writing a VCL application for windows using Embarcadero C++ builder XE 10.1 Berlin
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
ste5anSenior Developer

Commented:
Basically, yes. But about how much data are we talking? How complex is the XML structure?

Sometimes it is simpler to save the data set to disk (the SaveToFile method) as simple XML and use an XSLT transform to create the result.

btw, what's you backend? SQL Server for example can produce XML.

Author

Commented:
The backend is Microsoft SQL Server 2016.
The data isn't that large, maybe 20 - 30 records with each record having 6 columns.
The last column is a string which could ()optionally be further "decoded" into a further 9 columns of data each with up to 8 characters.
The software currently outputs data in a CSV format as originally requested but now has expressed a preference to export it in XML instead.
What is an XSLT Transform ?
ste5anSenior Developer

Commented:
I would look into SQL Servers XML capabilities first: the FOR XML clause. Look at the PATH() transformations first.

A XSLT transform is a XML style sheet describing how to transform XML to different outputs. E.g. HTML, text or reformatted XML.
>> Is it appropriate to use a TXMLDocument component and if so how would I do this ?
 From what I've read , I don't see why you couldn't use it for your fairly simple case.

Give the following CreateDocument a try:
#include <vcl.h>
#pragma hdrstop

#include <tchar.h>
#include <XMLDoc.hpp>
#include <XMLIntf.hpp>
#include <ComObj.hpp>
#include <stdio.h>

#pragma argsused

void CreateDocument();
void RetrieveDocument();
const _TCHAR* destPath = _TEXT("../../dest.xml"); // File should exist.
const _TCHAR* srcPath = destPath;

int _tmain(int argc, _TCHAR* argv[]) {

	CoInitializeEx(NULL, 0);

	try {
		CreateDocument();
		RetrieveDocument();
	}
	catch (Exception &ex) {
		printf("Exception message: %ls\n", ex.Message);
	}

	return 0;
}

void CreateDocument() {
	_di_IXMLDocument document = interface_cast<Xmlintf::IXMLDocument>
		(new TXMLDocument(NULL));
	document->Active = true;

	// Define document content.
	document->DocumentElement = document->CreateNode("ThisIsTheDocumentElement",
		ntElement, "");
	document->DocumentElement->Attributes["attrName"] = "attrValue";
	_di_IXMLNode nodeElement = document->DocumentElement->AddChild
		("ThisElementHasText", -1);
	nodeElement->Text = "Inner text.";
	_di_IXMLNode nodeCData = document->CreateNode("any characters here",
		ntCData, "");
	document->DocumentElement->ChildNodes->Add(nodeCData);
	_di_IXMLNode nodeText = document->CreateNode("This is a text node.",
		ntText, "");
	document->DocumentElement->ChildNodes->Add(nodeText);

	document->SaveToFile(destPath);
}

void RetrieveDocument() {
	const _di_IXMLDocument document = interface_cast<Xmlintf::IXMLDocument>
		(new TXMLDocument(NULL));
	document->LoadFromFile(srcPath);

	// Find a specific node.
	const _di_IXMLNode nodeElement =
		document->ChildNodes->FindNode("ThisIsTheDocumentElement");

	if (nodeElement != NULL) {
		// Get a specific attribute.
		puts("Getting attribute...");
		const _TCHAR* attrName = _TEXT("attrName");
		if (nodeElement->HasAttribute(attrName)) {
			const _TCHAR* attrValue = nodeElement->Attributes[attrName];
			printf("Attribute value: %ls\n", attrValue);
		}

		// Traverse child nodes.
		puts("\nTraversing child nodes...");
		for (int i = 0; i < nodeElement->ChildNodes->Count; i++) {
			const _di_IXMLNode node = nodeElement->ChildNodes->Get(i);
			// Display node name.
			printf("Node name: %ls\n", node->NodeName);
			// Check whether the node type is Text.
			if (node->NodeType == ntText) {
				// Display node text.
				printf("\tThis is a node of type Text. The text is: %ls\n",
					node->Text);
			}
			// Check whether the node is a text element.
			if (node->IsTextElement) {
				printf("\tThis is a text element. The text is: %ls\n",
					node->Text);
			}
		}
	}
}

Open in new window

http://docwiki.embarcadero.com/CodeExamples/Rio/en/TXMLDocument_use_case_(C%2B%2B)

Here is the class hierarchy and description:
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/XMLDoc_TXMLDocument.html

 I have read that TXMLDocument is not easy for newbies , but since your use case is fairly simple , this may work for you.

 However, in general , it is better to use more popular XML Doc writers so that if you run into trouble , you will have a larger group of people who can help you.

Author

Commented:
Thanks for your comments. The links to code examples and documentation were useful.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial