A quick way of of dumping table records into a xml-file is to use the kernel method xml, which is present on all instances of a tablebuffer. However, the xml produced by this method is NOT well-formed.
With a little adjustment to this method we can make the XML data output wellformed.
But first you must add this method to the GLOBAL class:
And now back to the global::XMLString method.
The last code block in the method is a big switch case construct handling all data types in x++. In the string handler section:
case Types::RSTRING:
case Types::VARSTRING:
case Types::STRING: r += legalXMLString(value);
break;
Insert this code just before the break-statement:
r = global::escapeHTMLChars(r);
To call the method mentioned above.
So the code will look like this:
case Types::RSTRING:
case Types::VARSTRING:
case Types::STRING:
r += legalXMLString(value);
r = global::escapeHTMLChars(r);
break;
Now it is possible to write code that:
{
query q;
QueryRun qr;
AsciiIo f;
f = new AsciiIo('\\\\axdev2\\e$\\CIT Files\\jas\\mcfly.xml','w');
if (!f)
throw error("Argh ! File can not be created.");
f.writeRaw('');
// Write root node
f.writeRaw('');
q = new Query();
// Get customer no. 0215
q.addDataSource(tablenum(CustTable)).addRange(fieldnum(CustTable,AccountNum)).value('0215');
qr = new QueryRun(q);
while (qr.next()) {
f.write(qr.get(tablenum(CustTable)).xml());
}
f.writeRaw('');
f = null;
// Show xml-file in browser
winapi::shellExecute('\\\\axdev2\\e$\\CIT Files\\jas\\mcfly.xml');
}
Three problems exists:
- No header info for the xml-document is written
- No root node is written
- The data within tags are not html escaped
With a little adjustment to this method we can make the XML data output wellformed.
But first you must add this method to the GLOBAL class:
public static str escapeHTMLChars(str _in)
{
int x;
str out;
for(x=1;x<=strlen(_in);x++)
{
if ((char2num(_in,x) < 32) && (char2num(_in,x) > 126))
{
out += '&#'+num2str(char2num(_in,x),0,0,0,0)+';';
}
else
{
out += substr(_in,x,1);
}
}
return out;
}
And now back to the global::XMLString method.
The last code block in the method is a big switch case construct handling all data types in x++. In the string handler section:
case Types::RSTRING:
case Types::VARSTRING:
case Types::STRING: r += legalXMLString(value);
break;
Insert this code just before the break-statement:
r = global::escapeHTMLChars(r);
To call the method mentioned above.
So the code will look like this:
case Types::RSTRING:
case Types::VARSTRING:
case Types::STRING:
r += legalXMLString(value);
r = global::escapeHTMLChars(r);
break;
Now it is possible to write code that:
- Writes an xml-header.
- Writes a root node tag.
- Iterates a table and calls the xml-method on the tablenbuffer.
- Write the end for the root node tag.
{
query q;
QueryRun qr;
AsciiIo f;
f = new AsciiIo('\\\\axdev2\\e$\\CIT Files\\jas\\mcfly.xml','w');
if (!f)
throw error("Argh ! File can not be created.");
f.writeRaw('');
// Write root node
f.writeRaw('
q = new Query();
// Get customer no. 0215
q.addDataSource(tablenum(CustTable)).addRange(fieldnum(CustTable,AccountNum)).value('0215');
qr = new QueryRun(q);
while (qr.next()) {
f.write(qr.get(tablenum(CustTable)).xml());
}
f.writeRaw('');
f = null;
// Show xml-file in browser
winapi::shellExecute('\\\\axdev2\\e$\\CIT Files\\jas\\mcfly.xml');
}
Minor syntax error it looks like:
ReplyDeleteif ((char2num(_in,x) < 32) (char2num(_in,x) > 126))
should be, I think:
if ((char2num(_in,x) < 32) && (char2num(_in,x) > 126))
Darn html-encoding. :)
ReplyDeleteCorrected. Thanx for the input.