mandag den 4. april 2011

A quick way of dumping records of a table in an xml-file.

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.

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
When the xml-method is called a call to the GLOBAL class method XMLString method is made.
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:
  1. Writes an xml-header.
  2. Writes a root node tag.
  3. Iterates a table and calls the xml-method on the tablenbuffer. 
  4. Write the end for the root node tag.
static void Job45(Args _args)
{
    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');
}

2 kommentarer:

  1. Minor syntax error it looks like:
    if ((char2num(_in,x) < 32) (char2num(_in,x) > 126))

    should be, I think:
    if ((char2num(_in,x) < 32) && (char2num(_in,x) > 126))

    SvarSlet
  2. Darn html-encoding. :)
    Corrected. Thanx for the input.

    SvarSlet