A Caché of Tips: XML

27 views
Skip to first unread message

Michael Cohen

unread,
Mar 26, 2012, 4:21:09 PM3/26/12
to InterSy...@googlegroups.com
XML files are annotated text files commonly used to exchange data.

For example a Person object or SQL Table row might include “John Smith” and “1976-07-04”.  That is the data.  But both SQL and objects know, among other things, that the first field is a Character Name, and the second is a Date DOB. That is the metadata.  XML provides a convenient format to exchange such data and metadata.

There is an optional Appendix at the end of this Tip with an intro to XML.

Caché provides a number of class methods to simplify reading and writing XML files.  The details are here:
http://docs.intersystems.com/cache20121/csp/docbook/DocBook.UI.Page.cls?KEY=GXMLPROJ

There are also many tools that work with XML.  For example, there is a free XML editor from Microsoft:
http://www.microsoft.com/download/en/details.aspx?id=7973


The following examples will:
1. create a class for the MV file PERSON mentioned above,
2. export a PERSON record to a text .xml file,
3. manually edit that file, and
4. import the result to create a new record.

We start with a file with 2 DICT entries and 1 data item:

MV:LIST DICT PERSON BY F2
 
LIST DICT PERSON BY F2            
Field............ CODE KEY.CODE CONV. FORMAT DISPLAY NAME SM ASSOC.....
Name
 
@ID               D           0       10L    PERSON       S
NAME              D           1       20L                 S
DOB               D           2 D4/   10L                 S
 
3 Items listed.
MV:LIST PERSON NAME DOB
 
LIST PERSON NAME DOB 
PERSON.... NAME................ DOB.......
 
1          John Smith           06/04/1984
 
One item listed.
MV:


Step 1. Create a class for the MV file PERSON.
You can either start by creating a class directly, or start with an MV file and use PROTOCLASS to create a class for you.  If you haven’t already installed PROTOCLASS, search the doc for it, and follow directions to install and configure.  A recent Tip on PROTOCLASS is available here:
https://sites.google.com/site/intersystemsmv/home/a-cache-of-tips/protoclass
Here I run it on my file.

MV:PROTOCLASS PERSON NAME DOB
Processing simple attribute definitions
Creating property called Name from NAME
Creating property called Dob from DOB
Processing computed attribute definitions
Saving the generated class...
Compiling the generated class...
 
Compilation started on 03/13/2012 18:02:58 with qualifiers 'cfvko3'
Compiling class MVFILE.PERSON
Compiling table MVFILE.PERSON
Compiling routine MVFILE.PERSON.1
Processing MV projection...
MV file name is 'PERSON'
MVREPOPULATE is False, skipping DICT update
 
Compilation finished successfully in 0.305s.
Class generation and compilation was successful!
MV:

This creates the following class:
Class MVFILE.PERSON Extends (%Persistent, %MV.Adaptor, %XML.Adaptor) [ ClassType = persistent, Inheritance = right, ProcedureBlock, SqlRowIdPrivate ]
{

Parameter MVAUTOLOCK = 0;

Parameter MVCLEARDICT = 0;

Parameter MVCREATE As BOOLEAN = 0;

/// Do not modify MVFILENAME if the file already exists.
Parameter MVFILENAME As STRING = "PERSON";

Parameter MVREPOPULATE = 0;

Property Dob As %MV.Date(MVATTRIBUTE = 2, MVAUTO = "P", MVNAME = "DOB", MVPROJECTED = 0, MVTODISPLAY = "D4/", MVTYPE = "D");

Property ItemId As %String;

Property Name As %String(COLLATION = "Space", MVATTRIBUTE = 1, MVAUTO = "P", MVNAME = "NAME", MVPROJECTED = 0, MVTYPE = "D");

Index indexItemId On ItemId [ IdKey, PrimaryKey ];

}

Note that, in addition to extending %MV.Adaptor, it also extends %XML.Adaptor.  This was generally not required, but was added in anticipation of uses such as this example.


Step 2. Export a record to an .xml file.
InterSystems has extended MVBasic to enable execution of object syntax, as well as allowing class methods to be written in MVBasic.  So there are a number of ways to export a record as an .xml file, such as:
   a. write a program to prompt for record ID and destination,
   b. write a subprogram that takes these args, or
   c. write a class method that takes these args.

This program is an example of a.
CRT "PERSON ID ": ; INPUT PID
CRT "DESTINATION LOCATION ": ; INPUT DEST ;* path to DEST must exist
PERS="MVFILE.PERSON"->%OpenId(PID)
IF ISOBJECT(PERS) ELSE CRT "NO SUCH PERSON"; STOP
WRITER="%XML.Writer"->%New()
WRITER->Indent=1 ;* else all on one line
STATUS=WRITER->OutputToFile(DEST)
IF STATUS#1 THEN "%SYSTEM.OBJ"->DisplayError(STATUS); STOP
STATUS=WRITER->RootObject(PERS)
IF STATUS#1 THEN "%SYSTEM.OBJ"->DisplayError(STATUS); STOP

I can run it:
MV:WRITE1
PERSON ID ?1
DESTINATION LOCATION ?D:\temp\Person1.xml

If I then open the generated file, I see my data, and metadata markups:

  <?xml version="1.0" encoding="UTF-8" ?>
- <PERSON>
  <Dob>1984-06-04</Dob>
  <ItemId>1</ItemId>
  <Name>John Smith</Name>
  </PERSON>


It is not much effort to export multiple records or more complex structures, or to change this to a subroutine with args to avoid prompting.

You could also use the Web Service Wizard to produce a similar result.  In either case, there are options to control what is returned and how it is formatted.


Option c. was to create a similar class method.  I added this to my PERSON class.

ClassMethod CreateXML(ID As %Integer, Destination As %String) As %Status [ Language = mvbasic ]
{
    PERS=@ME->%OpenId(ID)
    IF ISOBJECT(PERS) ELSE RETURN "%SYSTEM.Status"->Error(401,"NO SUCH PERSON")
    WRITER="%XML.Writer"->%New()
    WRITER->Indent=1 ;* else all on one line
    STATUS=WRITER->OutputToFile(Destination)
    IF STATUS#1 THEN RETURN STATUS
    STATUS=WRITER->RootObject(PERS)
    RETURN STATUS
}

Executing it produces the same result as above.

MV:;STATUS="MVFILE.PERSON"->CreateXML(1,"D:\temp\P1.xml")
MV:;IF STATUS#1 THEN "%SYSTEM.Status"->DisplayError(STATUS)


Step 3. Next, I will manually edit the file to pretend that the file was sent to me by another system.

I could use a text editor such as Notepad, or for more complex files, an XML editor.  Or I could generate such a file programatically.

The result is PERSON2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<PERSON>
  <Dob>1975-03-21</Dob>
  <ItemId>2</ItemId>
  <Name>Mary Jones</Name>
</PERSON>


Step 4. Now I want to read this file and add the indicated record to my MV file.
The following program reads in the file.  Since the file contains metadata such as field names, the Correlate method is able to map the supplied data in the PERSON element to MVFILE.PERSON object properties.  It is then just a matter of %Save().

MV:CT BP READ1
 
     READ1
0001 READER = "%XML.Reader"->%New()
0002 CRT "Full path to source xml file"; INPUT FILE
0003 STATUS = READER->OpenFile(FILE)
0004 CRT "OpenFile status: ":STATUS
0005 READER->Correlate("PERSON","MVFILE.PERSON")
0006 READER->Next(OBJECT,STATUS)
0007 CRT "Next STATUS: ":STATUS
0008 CRT "Name: ":OBJECT->Name
0009 STATUS=OBJECT->%Save()
0010 CRT "%Save status: ":STATUS
MV:

Here I run the program.
MV:READ1
Full path to source xml file
?D:\temp\Person2.xml
OpenFile status: 1
Next STATUS: 1
Name: Mary Jones
%Save status: 1
MV:

And back at TCL I can see the new record.

MV:LIST PERSON NAME DOB
 
LIST PERSON NAME DOB
PERSON.... NAME................ DOB.......
 
1          John Smith           06/04/1984
2          Mary Jones           03/21/1975
 
2 Items listed.
MV:

There are many more things that you can do with XML, such as reading and writing character and stream data.  A forthcoming Tip will discuss streams.

---------------------------------------------------
Appendix re XML
---------------
In the old days, computer systems would exchange data via decks of punched cards (or magnetic tape equivalent), typically with predetermined, fixed-width fields.  If the reader inadvertently used the wrong layout, they would get incorrect results.

One solution to this used by many modern Electronic Data Interchange systems involves the use of XML to include the field info with the data.

eXtensible Markup Language (XML) is a markup language that defines a set of rules for encoding documents in a format that is both human-readable and machine-readable.  The result is a text file that contains both data and metadata (data about the data).  A markup language specifies the rules that specify how to create such documents so that the content can be distinguished from the markups (annotations). For example, Microsoft Word documents can contain markups to specify bold, font, size, color, paragraph, etc.  An extensible markup language allows the developer of the document to define additional markup tags.

For example a Person object or SQL Table row might include “John Smith” and “1976-07-04”.  That is the data.  But both SQL and objects know, among other things, that the first field is a Character Name, and the second is a Date DOB. That is the metadata. 

XML specifies a way to structure such data and metadata.  It was specified in a number of open standards by W3C, and others.

Web browsers display web pages with fonts, colors and pictures.  But if you ask to view the source for the web page, you see plain text.  Included in the text are special strings that tell the browser how to display the text, but that are not themselves displayed.  They are the markups, which begin with a ‘<’ and end with a ‘>’.  For example, ‘<p> ‘ instructs the browser to start a new paragraph.  Web services also use XML.  Companies using electronic data interchange typically exchange XML files.


On my android phone I run an app that displays the current temp and forecast, as well as an image showing sunny, cloudy, rain, snow, etc.

Google provides an API that makes this simple.  If I point my web browser to:
http://www.google.com/ig/api?weather=Boston+MA
an XML file is returned.  It is formatted by the browser with color, bold and carriage returns to make it more readable.  My phone can read this file.  For example, it currently includes the following:
<current_conditions>
  <condition data="Cloudy" />
  <temp_f data="69" />
  <temp_c data="21" />
  <humidity data="Humidity: 54%" />
  <icon data="/ig/images/weather/cloudy.gif" />
  <wind_condition data="Wind: SW at 17 mph" />
  </current_conditions>

The phone app can analyze this and find the data it wishes to display, and present it on my screen.

Database users sometimes need to do EDI, to export data to another system, or import data.  XML documents are a convenient way to do this.


Reply all
Reply to author
Forward
0 new messages