Example: generating XML
The following example simulates the building of a purchase order in a group data item, and generates an XML version of that purchase order.
Program XGFX uses XML GENERATE
to produce XML
output in elementary data item xmlPO
from the source
record, group data item purchaseOrder
. Elementary
data items in the source record are converted to character format
as necessary, and the characters are inserted as the
values of XML attributes whose names are derived from the data-names
in the source record.
XGFX calls program Pretty
,
which uses the XML PARSE
statement with processing
procedure p
to format the XML output with new lines
and indentation so that the XML content can more easily be verified.
Program XGFX
Identification division.
Program-id. XGFX.
Data division.
Working-storage section.
01 numItems pic 99 global.
01 purchaseOrder global.
05 orderDate pic x(10).
05 shipTo.
10 country pic xx value 'US'.
10 name pic x(30).
10 street pic x(30).
10 city pic x(30).
10 state pic xx.
10 zip pic x(10).
05 billTo.
10 country pic xx value 'US'.
10 name pic x(30).
10 street pic x(30).
10 city pic x(30).
10 state pic xx.
10 zip pic x(10).
05 orderComment pic x(80).
05 items occurs 0 to 20 times depending on numItems.
10 item.
15 partNum pic x(6).
15 productName pic x(50).
15 quantity pic 99.
15 USPrice pic 999v99.
15 shipDate pic x(10).
15 itemComment pic x(40).
01 numChars comp pic 999.
01 xmlPO pic x(999).
Procedure division.
m.
Move 20 to numItems
Move spaces to purchaseOrder
Move '1999-10-20' to orderDate
Move 'US' to country of shipTo
Move 'Alice Smith' to name of shipTo
Move '123 Maple Street' to street of shipTo
Move 'Mill Valley' to city of shipTo
Move 'CA' to state of shipTo
Move '90952' to zip of shipTo
Move 'US' to country of billTo
Move 'Robert Smith' to name of billTo
Move '8 Oak Avenue' to street of billTo
Move 'Old Town' to city of billTo
Move 'PA' to state of billTo
Move '95819' to zip of billTo
Move 'Hurry, my lawn is going wild!' to orderComment
Move 0 to numItems
Call 'addFirstItem'
Call 'addSecondItem'
Move space to xmlPO
Xml generate xmlPO from purchaseOrder count in numChars
with xml-declaration with attributes
namespace 'http://www.example.com' namespace-prefix 'po'
Call 'pretty' using xmlPO value numChars
Goback
.
Identification division.
Program-id. 'addFirstItem'.
Procedure division.
Add 1 to numItems
Move '872-AA' to partNum(numItems)
Move 'Lawnmower' to productName(numItems)
Move 1 to quantity(numItems)
Move 148.95 to USPrice(numItems)
Move 'Confirm this is electric' to itemComment(numItems)
Goback.
End program 'addFirstItem'.
Identification division.
Program-id. 'addSecondItem'.
Procedure division.
Add 1 to numItems
Move '926-AA' to partNum(numItems)
Move 'Baby Monitor' to productName(numItems)
Move 1 to quantity(numItems)
Move 39.98 to USPrice(numItems)
Move '1999-05-21' to shipDate(numItems)
Goback.
End program 'addSecondItem'.
End program XGFX.
Program Pretty
Identification division.
Program-id. Pretty.
Data division.
Working-storage section.
01 prettyPrint.
05 pose pic 999.
05 posd pic 999.
05 depth pic 99.
05 inx pic 999.
05 elementName pic x(30).
05 indent pic x(40).
05 buffer pic x(998).
05 lastitem pic 9.
88 unknown value 0.
88 xml-declaration value 1.
88 element value 2.
88 attribute value 3.
88 charcontent value 4.
Linkage section.
1 doc.
2 pic x occurs 16384 times depending on len.
1 len comp-5 pic 9(9).
Procedure division using doc value len.
m.
Move space to prettyPrint
Move 0 to depth
Move 1 to posd pose
Xml parse doc processing procedure p
Goback
.
p.
Evaluate xml-event
When 'VERSION-INFORMATION'
String '<?xml version="' xml-text '"' delimited by size
into buffer with pointer posd
Set xml-declaration to true
When 'ENCODING-DECLARATION'
String ' encoding="' xml-text '"' delimited by size
into buffer with pointer posd
When 'STANDALONE-DECLARATION'
String ' standalone="' xml-text '"' delimited by size
into buffer with pointer posd
When 'START-OF-ELEMENT'
Evaluate true
When xml-declaration
String '?>' delimited by size into buffer
with pointer posd
Set unknown to true
Perform printline
Move 1 to posd
When element
String '>' delimited by size into buffer
with pointer posd
When attribute
String '">' delimited by size into buffer
with pointer posd
End-evaluate
If elementName not = space
Perform printline
End-if
Move xml-text to elementName
Add 1 to depth
Move 1 to pose
Set element to true
String '<' xml-text delimited by size
into buffer with pointer pose
Move pose to posd
When 'ATTRIBUTE-NAME'
If element
String ' ' delimited by size into buffer
with pointer posd
Else
String '" ' delimited by size into buffer
with pointer posd
End-if
String xml-text '="' delimited by size into buffer
with pointer posd
Set attribute to true
When 'ATTRIBUTE-CHARACTERS'
String xml-text delimited by size into buffer
with pointer posd
When 'ATTRIBUTE-CHARACTER'
String xml-text delimited by size into buffer
with pointer posd
When 'CONTENT-CHARACTERS'
Evaluate true
When element
String '>' delimited by size into buffer
with pointer posd
When attribute
String '">' delimited by size into buffer
with pointer posd
End-evaluate
String xml-text delimited by size into buffer
with pointer posd
Set charcontent to true
When 'CONTENT-CHARACTER'
Evaluate true
When element
String '>' delimited by size into buffer
with pointer posd
When attribute
String '">' delimited by size into buffer
with pointer posd
End-evaluate
String xml-text delimited by size into buffer
with pointer posd
Set charcontent to true
When 'END-OF-ELEMENT'
Move space to elementName
Evaluate true
When element
String '/>' delimited by size into buffer
with pointer posd
When attribute
String '"/>' delimited by size into buffer
with pointer posd
When other
String '</' xml-text '>' delimited by size
into buffer with pointer posd
End-evaluate
Set unknown to true
Perform printline
Subtract 1 from depth
Move 1 to posd
When other
Continue
End-evaluate
.
printline.
Compute inx = function max(0 2 * depth - 2) + posd - 1
If inx > 120
compute inx = 117 - function max(0 2 * depth - 2)
If depth > 1
Display indent(1:2 * depth - 2) buffer(1:inx) '...'
Else
Display buffer(1:inx) '...'
End-if
Else
If depth > 1
Display indent(1:2 * depth - 2) buffer(1:posd - 1)
Else
Display buffer(1:posd - 1)
End-if
End-if
.
End program Pretty.
Output from program XGFX
<?xml version="1.0" encoding="ISO-8859-1"?>
<po:purchaseOrder xmlns:po="http://www.example.com" orderDate="1999-10-20" orderComment="Hurry, my lawn is going wild!">
<po:shipTo country="US" name="Alice Smith" street="123 Maple Street" city="Mill Valley" state="CA" zip="90952"/>
<po:billTo country="US" name="Robert Smith" street="8 Oak Avenue" city="Old Town" state="PA" zip="95819"/>
<po:items>
<po:item partNum="872-AA" productName="Lawnmower" quantity="1" USPrice="148.95" shipDate=" " itemComment="Confirm...
</po:items>
<po:items>
<po:item partNum="926-AA" productName="Baby Monitor" quantity="1" USPrice="39.98" shipDate="1999-05-21" itemComme...
</po:items>
</po:purchaseOrder>