You are on page 1of 278

Front cover

XML Processing on
z/OS
Overview of XML generation and
parsing technologies available on z/OS

Code samples for z/OS XML


Systems Services and Toolkit

XML features for COBOL,


PL/I, DB2 pureXML, and CICS

Mike Ebbers
Mogens Conrad
Hans-Dieter Mertiens
Nagesh Subrahmanyam
Michael Todd

ibm.com/redbooks
International Technical Support Organization

XML Processing Options on z/OS

December 2009

SG24-7810-00
Note: Before using this information and the product it supports, read the information in “Notices” on
page xv.

First Edition (December 2009)

This edition applies to Version 1 Release 11 of XML for z/OS.

© Copyright International Business Machines Corporation 2009. All rights reserved.


Note to U.S. Government Users Restricted Rights -- Use, duplication or disclosure restricted by GSA ADP Schedule
Contract with IBM Corp.
Contents

Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix

Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi

Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii

Notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
Trademarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvi

Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
The team who wrote this book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
Become a published author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
Comments welcome. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix

Chapter 1. XML essentials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1


1.1 Introduction to XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.1 DTD. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 XML schema definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2.1 XML schema options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2.2 xsd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.3 Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.4 Encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.5 XML 1.0 and XML 1.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.6 XML processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.6.1 Well-formedness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.6.2 Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.7 Industry formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.8 XML parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.8.1 SAX: Simple API for XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.8.2 DOM: Document Object Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.8.3 Less common parsing methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.9 XML Transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

Chapter 2. Overview of XML processing on System z. . . . . . . . . . . . . . . . . . . . . . . . . . 15


2.1 z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.2 XML Toolkit for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.3 Enterprise COBOL for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.3.1 COBOL XML generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.3.2 COBOL XML parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.4 Enterprise PL/I for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.4.1 PL/I XML generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.4.2 PL/I XML parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.5 CICS Transaction Server for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.6 IMS XML DB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.7 Rational Developer for System z. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.8 Java-centric processing of XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.9 pureXML on DB2 9 for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.10 Linux for System z. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

Chapter 3. XML sources, targets, and design patterns . . . . . . . . . . . . . . . . . . . . . . . . . 25

© Copyright IBM Corp. 2009. All rights reserved. iii


3.1 Common points of Entry and Exit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.1.1 XML documents as files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.1.2 Messaging transports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.1.3 Web services through HTTP/SOAP requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.1.4 Generated and consumed on z. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.2 XML processing models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.2.1 File triggered batch jobs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.2.2 Scheduled batch jobs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.2.3 Web services and DB2, IMS, CICS TS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.2.4 WebSphere Application Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.2.5 Enterprise Service Bus, MQ Message Broker, Process Server . . . . . . . . . . . . . . 32
3.2.6 DB2 as an XML warehouse and middle tier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.2.7 IMS as an XML warehouse and middle tier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.2.8 Messaging interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

Chapter 4. Overview of XML generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37


4.1 Enterprise COBOL for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
4.2 Enterprise PL/I for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
4.3 4.3 CICS TS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
4.4 Web Services in CICS TS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
4.5 XML Toolkit for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
4.6 DB2 for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

Chapter 5. How to generate XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41


5.1 Generating XML from COBOL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
5.1.1 COBOL XML GENERATE examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
5.1.2 XML GENERATE error handling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
5.1.3 COBOL reserved words as element and attribute names. . . . . . . . . . . . . . . . . . . 46
5.1.4 Hyphens in element names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
5.1.5 Upper-case element names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
5.1.6 COBOL data attributes that suppress XML string generation . . . . . . . . . . . . . . . . 47
5.1.7 Multi-byte character encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.2 Generating XML from PL/I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5.3 XML Toolkit for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.4 Generating XML from CICS Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5.4.1 CICS Web Services Assistant. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.5 CICS Transform statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
5.6 DB2 for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

Chapter 6. Overview of parsing technologies on z/OS . . . . . . . . . . . . . . . . . . . . . . . . . 65


6.1 z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
6.1.1 Parsed XML data stream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
6.1.2 Programming interface provided by XML System Services . . . . . . . . . . . . . . . . . 68
6.1.3 Buffer handling with XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
6.1.4 General scheme for invoking z/OS XML System Services for parsing . . . . . . . . . 70
6.1.5 Optimized schema representation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
6.1.6 Concept of StringID. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
6.2 XML Toolkit on z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
6.2.1 Parsing with XML Toolkit for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
6.2.2 Parsing and validation with XML Toolkit on z/OS . . . . . . . . . . . . . . . . . . . . . . . . . 78
6.2.3 Parsing and source offsets with XML Toolkit on z/OS . . . . . . . . . . . . . . . . . . . . . 79
6.3 Transforming XML documents with XML Toolkit for z/OS. . . . . . . . . . . . . . . . . . . . . . . 80
6.4 Newer features to handle XML on z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
6.4.1 Enterprise PL/I for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

iv XML Processing Options on z/OS


6.4.2 Enterprise COBOL for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
6.5 Parsing with pureXML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
6.6 Storing XML within DB2 for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

Chapter 7. Processing components, relationships, and options . . . . . . . . . . . . . . . . . 85


7.1 Application programs and z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . . . . 86
7.1.1 Enterprise COBOL for z/OS applications and z/OS XML System Services . . . . . 86
7.1.2 Enterprise PL/I for z/OS programs and XML System Services on z/OS. . . . . . . . 87
7.1.3 Assembler, C, and XML System Services on z/OS . . . . . . . . . . . . . . . . . . . . . . . 88
7.1.4 C++ and z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
7.1.5 Software outside the usual scope of a TCB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
7.2 When to use the XML Toolkit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
7.2.1 XML document transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
7.2.2 Implementing C or C++ applications using XML parser classes. . . . . . . . . . . . . . 89
7.2.3 Invoking the XML Toolkit XSLT Processor from within COBOL-PL/I
applications. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
7.2.4 Invoking the XML Toolkit Parser from within COBOL-PL/I applications . . . . . . . . 90
7.3 When to use the z/OS XML System Services parsers . . . . . . . . . . . . . . . . . . . . . . . . . 90
7.3.1 When to use the z/OS XML System Services parser . . . . . . . . . . . . . . . . . . . . . . 90
7.3.2 When to use the COBOL native parser. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
7.3.3 When to use the z/OS XML parser rather than the PL/I native parser . . . . . . . . . 91
7.3.4 When to change from COBOL and PL/I native parsers to z/OS XML
System Services parsers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

Chapter 8. How to parse XML. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93


8.1 Parsing Using z/OS XML System Services. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
8.1.1 Non-validating Parsing using z/OS XML System Services . . . . . . . . . . . . . . . . . . 94
8.1.2 Validating parsing using z/OS XML System Services. . . . . . . . . . . . . . . . . . . . . . 95
8.2 XML Toolkit for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
8.2.1 SAX parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
8.2.2 DOM parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
8.3 COBOL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
8.4 PL/I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
8.5 CICS Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
8.5.1 CICS Web Services Assistant. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
8.6 CICS Transform statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
8.7 Parsing with pureXML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
8.7.1 Simple DB2 parsing without validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
8.7.2 Simple DB2 parsing with validation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110

Chapter 9. Hints, tips, and samples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113


9.1 Validation using optimized schema representation (OSR) . . . . . . . . . . . . . . . . . . . . . 114
9.1.1 Creating an OSR. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
9.1.2 Parse with validation: Using the OSR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
9.1.3 Basic flow of a program to handle parsed data. . . . . . . . . . . . . . . . . . . . . . . . . . 117
9.1.4 Basic loop to manage the input and output buffer . . . . . . . . . . . . . . . . . . . . . . . 119
9.1.5 Detailed view at the parsed data stream. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
9.1.6 Get a StringID exit working . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
9.1.7 Extracting a StringID Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
9.2 Using the language bindings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
9.2.1 Assembler interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
9.2.2 C/C++ language bindings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133

Chapter 10. Performance recommendations and cost perspectives . . . . . . . . . . . . . 135

Contents v
10.1 Where and when to validate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
10.2 XPLINK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
10.2.1 XML Toolkit for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
10.2.2 z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
10.2.3 COBOL and PL/I built-in parsers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
10.3 zIIPs and zAAPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
10.3.1 zAAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
10.3.2 zIIP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
10.3.3 zAAP on zIIP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
10.4 Encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
10.4.1 XML Toolkit for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
10.4.2 z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
10.4.3 COBOL and PL/I built-in parsers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
10.5 Application language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
10.5.1 COBOL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
10.5.2 PL/I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
10.5.3 C and C++. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
10.5.4 Assembler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
10.5.5 Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143

Chapter 11. XML and character encoding issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145


11.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
11.1.1 Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
11.2 UTF schemes and System z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
11.2.1 Advantages of using Unicode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
11.2.2 Character encoding schemes supported on System z . . . . . . . . . . . . . . . . . . . 148
11.2.3 z/OS XML Toolkit and z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . 148
11.2.4 Enterprise COBOL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
11.2.5 Enterprise PL/I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
11.3 Encoding examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
11.3.1 EBCDIC XML document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
11.3.2 UTF-8 XML document. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
11.3.3 UTF-16BE XML document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
11.3.4 UTF-16LE XML document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
11.4 Exchanging XML documents between heterogeneous systems. . . . . . . . . . . . . . . . 158
11.4.1 HTTP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
11.4.2 WebSphere MQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
11.4.3 FTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
11.4.4 DB2 database and encoding considerations . . . . . . . . . . . . . . . . . . . . . . . . . . 160
11.4.5 CICS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
11.4.6 Saving ASCII files on System z. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

Appendix A. Supported character encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163


Supported code pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164

Appendix B. Program source files. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165


B.1 PL/I example to generate XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
B.2 PL/I program to call z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
B.3 C program to extract the StringIDTable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
B.4 Enterprise COBOL program to query XML document declaration . . . . . . . . . . . . . . . 180
B.5 C program to query XML document declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
B.6 Enterprise COBOL program to invoke z/OS XML System Services parser without
validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
B.7 Enterprise COBOL program to invoke z/OS XML System Services parser with a string ID

vi XML Processing Options on z/OS


exit (without validation) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
B.8 C program to traverse a z/OS XML parsed record stream
and display the information in it . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223

Appendix C. Additional material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239


Locating the Web material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
Using the Web material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
System requirements for downloading the Web material . . . . . . . . . . . . . . . . . . . . . . . 239
How to use the Web material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240

Abbreviations and acronyms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241

Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243

Related publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245


IBM Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
Other publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
Online resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
How to get Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
Help from IBM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247

Contents vii
viii XML Processing Options on z/OS
Figures

1-1 XML from Example 1-1 on page 2 transformed to HTML using XSLT stylesheet. . . . . 13
2-1 XML Toolkit for z/OS architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2-2 Parsing architecture for Enterprise COBOL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2-3 PL/I and z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2-4 CICS Transaction Server XML architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2-5 IMS DB XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2-6 DB2 with pureXML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3-1 CICS TS and XML/SOAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3-2 CICS transform statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3-3 IMS Web Services connectivity solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3-4 IMS and Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3-5 DB2 as a Web services provider. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3-6 DB2 as a Web services consumer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3-7 WebSphere Application Server and SOAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3-8 Enterprise Service Bus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3-9 DB2 as an XML warehouse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3-10 IMS as a middle tier or warehouse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3-11 IMS as a Java/XML application server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3-12 MQ messaging triggered listener applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
4-1 CICS as a service requester . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
5-1 HTML result from XSLT transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5-2 CICS as Web services requester . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5-3 CICS Web Services Assistant. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
6-1 z/OS XML System Services parsed data stream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
6-2 Buffers usages and flow in XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
6-3 Flowchart for invoking z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
6-4 One way of invoking z/OS XML System Services parser in case of x’1302’ reason code
74
6-5 String ID exit processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
6-6 Flow of parsing with existing parsers (top) and z/OS-specific parsers (bottom) . . . . . . 77
6-7 Validating parse with z/OS-specific classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
7-1 COBOL and z/OS XML System Services combinations . . . . . . . . . . . . . . . . . . . . . . . . 86
7-2 PL/I and z/OS XML System Services combinations . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
7-3 Invoking the XML toolkit from within COBOL-PL/I, single document input . . . . . . . . . . 89
7-4 Invoking the XML Toolkit from within COBOL-PL/I for multiple input documents . . . . . 89
7-5 Invoking the XML toolkit from within COBOL-PL/I for a single output document . . . . . 90
8-1 Simple non-validating parsing using z/OS XML System Services . . . . . . . . . . . . . . . . 94
8-2 Non-validating parsing with z/OS XML System Services using String IDs . . . . . . . . . . 94
8-3 Non-validating z/OS XML System Services parsing with a predefined set of String ID
values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
8-4 Two-step validating parse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
8-5 One-step validating parse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
8-6 Validating parse with predefined String ID assignments. . . . . . . . . . . . . . . . . . . . . . . . 97
8-7 Validating parse with predefined String ID assignments returning String IDs. . . . . . . . 98
8-8 Validating parse returning predefined String IDs and the OSR’s String ID table . . . . . 99
8-9 SAX parsing main program overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
8-10 Overview of document handler in SAX parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
8-11 DOM parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

© Copyright IBM Corp. 2009. All rights reserved. ix


8-12 DOM tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
8-13 CICS as a Service Provider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
8-14 CICS Web Services Assistant. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
9-1 Creating a string ID handler exit routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
9-2 System services parameter area for the GXLESTRI StringIDHandler exit . . . . . . . . . 124
9-3 System Services Vector passed to XML System Services . . . . . . . . . . . . . . . . . . . . . 126
9-4 System services parameter area for the GXLE1IDI StringIDHandler exit. . . . . . . . . . 129
10-1 XML processing eligible for zAAP or zIIP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
10-2 Overview XML processing from COBOL application . . . . . . . . . . . . . . . . . . . . . . . . 140
10-3 Overview XML processing from PL/I Application . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
10-4 Overview XML processing from C or C++ Application . . . . . . . . . . . . . . . . . . . . . . . 142
10-5 Overview XML processing from Assembler application . . . . . . . . . . . . . . . . . . . . . . 142
10-6 Overview XML processing from Java application . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
11-1 Windows Notepad dialog box with encoding option highlighted . . . . . . . . . . . . . . . . 154

x XML Processing Options on z/OS


Tables

1-1 Well-formed XML documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9


1-2 Standard XML schemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
A-1 List of supported encodings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164

© Copyright IBM Corp. 2009. All rights reserved. xi


xii XML Processing Options on z/OS
Examples

1-1 Simple XML document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2


1-2 External DTD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1-3 XML document with reference to external DTD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1-4 XML document with internal DTD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1-5 XML Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1-6 Corresponding Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1-7 XML document with duplicated element names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1-8 XML document using namespace prefixes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1-9 XML document using default namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1-10 XML Namespace declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1-11 XML Encoding Declaration for Unicode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1-12 XML Encoding Declarations for EBCDIC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1-13 XSLT stylesheet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5-1 COBOL XML GENERATE examples data description . . . . . . . . . . . . . . . . . . . . . . . . . 42
5-2 COBOL XML GENERATE basic element-style. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
5-3 COBOL XML GENERATE with XML declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
5-4 COBOL XML GENERATE Attribute-Style. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5-5 COBOL XML GENERATE with namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5-6 COBOL test of illegal characters. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
5-7 COBOL hyphen in tag names to underscore routine . . . . . . . . . . . . . . . . . . . . . . . . . . 46
5-8 Output from a PL/I program using XMLCHAR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5-9 Output from the MEMCONVERT built-in function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5-10 XML document before transformation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
5-11 XSLT used to transform XML to HTML page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5-12 Xalan command line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5-13 HTML output from Xalan command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
5-14 JCL to compile SMPLTRNS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5-15 JCL to link-edit the program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5-16 Same transformation using JCL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5-17 Changed source code for SimpleTransform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
5-18 CICS Web Services Assistant, JCL Sample, DFHLS2WS . . . . . . . . . . . . . . . . . . . . . 58
5-19 Transform statement: Data to XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
5-20 DB2 XMLELEMENT function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
5-21 DB2 XMLSERIALIZE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5-22 DB2 XMLSERIALIZE returning to a UTF-8 host variable . . . . . . . . . . . . . . . . . . . . . . 61
5-23 DB2 XMLAGG array of element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5-24 DB2 XMLCONCAT array of element list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
5-25 DB2 XMLELEMENT adding a parent element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
5-26 DB2 XMLELEMENT return binary column in base64 . . . . . . . . . . . . . . . . . . . . . . . . . 63
5-27 DB2 XMLATTRIBUTES to generate attribute-style XML string . . . . . . . . . . . . . . . . . 63
5-28 DB2 Complete document with declaration and root element . . . . . . . . . . . . . . . . . . . 64
6-1 COBOL XMLPARSE with validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
6-2 COBOL/SQL examples of storing XML within DB2. . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
8-1 Document handler interface description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
8-2 XML Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
8-3 DOMNode interface description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
8-4 CICS Web Services Assistant, JCL Sample, DFHLS2WS . . . . . . . . . . . . . . . . . . . . . 108
8-5 Transform statement, parse XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

© Copyright IBM Corp. 2009. All rights reserved. xiii


8-6 Transform statement, parse XML, with ELEMNAME option . . . . . . . . . . . . . . . . . . . . 109
8-7 Transform statement, unknown XML schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
8-8 DB2 parse without validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
8-9 DB2 commands to register an XML schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
8-10 DB2 insert with XML validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
9-1 Example JCL to run xsdosrg in batch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
9-2 Example of environment settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
9-3 Schema, list of xsd files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
9-4 Output from the OSRGEN tool in batch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
9-5 Directory listing to check the generated OSR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
9-6 Sequence of call to XML System Services to do a validated parse . . . . . . . . . . . . . . 117
9-7 Program flow for navigating XML parsed data stream . . . . . . . . . . . . . . . . . . . . . . . . 117
9-8 Error checking for navigating XML parsed data stream . . . . . . . . . . . . . . . . . . . . . . . 119
9-9 Simple XML string to be parsed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
9-10 Buffer retuned by the parser with simple decoding . . . . . . . . . . . . . . . . . . . . . . . . . . 121
9-11 Prolog for a METAL C program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
9-12 Conditional include for DSA handling in bare Metal C . . . . . . . . . . . . . . . . . . . . . . . 125
9-13 How to fill the system services vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
9-14 Passing system services parameter to the x/OS XML parser. . . . . . . . . . . . . . . . . . 126
9-15 XML System Services parameter for GXLE1IDI . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
9-16 Output buffer with string IDs from GXLESTRI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
9-17 StringID to string conversion with GXLESTRI. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
9-18 PL/I structure used as system services parameter for GXLE1IDI. . . . . . . . . . . . . . . 129
9-19 Output from a parser using GXLE1IDI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
9-20 StringIDTable listing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
9-21 Call gxlini from a PL/I program going through the CVT. . . . . . . . . . . . . . . . . . . . . . . 132
9-22 Defining a service using the options() in PL/I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
9-23 PL/I compile, bind and go with modification to include SYS1.CSSLIB . . . . . . . . . . . 133
9-24 Turning on the XPLINK link from within a C/C++ program . . . . . . . . . . . . . . . . . . . . 134
9-25 Command to compile and link a C/C++ program from the z/OS UNIX shell. . . . . . . 134
11-1 iconv() syntax for converting to different code set . . . . . . . . . . . . . . . . . . . . . . . . . . 149
11-2 XML document with EBCDIC encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
11-3 Result of GXL1QXD service for IBM01141 encoded XML document . . . . . . . . . . . . 153
11-4 Result (XML flags) of GXL1QXD service for IBM01141 encoded XML document . . 153
11-5 XML document with UTF-8 encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
11-6 Result of GXL1QXD service for UTF-8 encoded XML document . . . . . . . . . . . . . . . 155
11-7 Result (XML flags) of GXL1QXD service for UTF-8 encoded XML document . . . . . 155
11-8 XML document with UTF-16BE encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
11-9 Result of GXL1QXD service for UTF-16BE encoded XML document . . . . . . . . . . . 156
11-10 Result (XML flags) of GXL1QXD service for UTF-16BE encoded XML document . 157
11-11 HTTP header with character encoding declaration . . . . . . . . . . . . . . . . . . . . . . . . . 158
B-1 PL/I Generate XML example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
B-2 Simple PL/I program to parse without validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
B-3 C program to extract the STringIDTable. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
B-4 Enterprise COBOL program to call GXL1QXD program. . . . . . . . . . . . . . . . . . . . . . . 180
B-5 Querying the sample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
B-6 C program to extract basic XML document information . . . . . . . . . . . . . . . . . . . . . . . 183
B-7 COBOL program calling z/OS XML System Services on z/OS for parsing . . . . . . . . 187
B-8 Enterprise COBOL program for parsing (without validation) and buffer management. 202
B-9 C code to traverse an XML parsed record stream . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
B-10 Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
B-11 Output of the code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237

xiv XML Processing Options on z/OS


Notices

This information was developed for products and services offered in the U.S.A.

IBM may not offer the products, services, or features discussed in this document in other countries. Consult
your local IBM representative for information on the products and services currently available in your area. Any
reference to an IBM product, program, or service is not intended to state or imply that only that IBM product,
program, or service may be used. Any functionally equivalent product, program, or service that does not
infringe any IBM intellectual property right may be used instead. However, it is the user's responsibility to
evaluate and verify the operation of any non-IBM product, program, or service.

IBM may have patents or pending patent applications covering subject matter described in this document. The
furnishing of this document does not give you any license to these patents. You can send license inquiries, in
writing, to:
IBM Director of Licensing, IBM Corporation, North Castle Drive, Armonk, NY 10504-1785 U.S.A.

The following paragraph does not apply to the United Kingdom or any other country where such
provisions are inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION
PROVIDES THIS PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR
IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of
express or implied warranties in certain transactions, therefore, this statement may not apply to you.

This information could include technical inaccuracies or typographical errors. Changes are periodically made
to the information herein; these changes will be incorporated in new editions of the publication. IBM may make
improvements and/or changes in the product(s) and/or the program(s) described in this publication at any time
without notice.

Any references in this information to non-IBM Web sites are provided for convenience only and do not in any
manner serve as an endorsement of those Web sites. The materials at those Web sites are not part of the
materials for this IBM product and use of those Web sites is at your own risk.

IBM may use or distribute any of the information you supply in any way it believes appropriate without incurring
any obligation to you.

Information concerning non-IBM products was obtained from the suppliers of those products, their published
announcements or other publicly available sources. IBM has not tested those products and cannot confirm the
accuracy of performance, compatibility or any other claims related to non-IBM products. Questions on the
capabilities of non-IBM products should be addressed to the suppliers of those products.

This information contains examples of data and reports used in daily business operations. To illustrate them
as completely as possible, the examples include the names of individuals, companies, brands, and products.
All of these names are fictitious and any similarity to the names and addresses used by an actual business
enterprise is entirely coincidental.

COPYRIGHT LICENSE:

This information contains sample application programs in source language, which illustrate programming
techniques on various operating platforms. You may copy, modify, and distribute these sample programs in
any form without payment to IBM, for the purposes of developing, using, marketing or distributing application
programs conforming to the application programming interface for the operating platform for which the sample
programs are written. These examples have not been thoroughly tested under all conditions. IBM, therefore,
cannot guarantee or imply reliability, serviceability, or function of these programs.

© Copyright IBM Corp. 2009. All rights reserved. xv


Trademarks
IBM, the IBM logo, and ibm.com are trademarks or registered trademarks of International Business Machines
Corporation in the United States, other countries, or both. These and other IBM trademarked terms are
marked on their first occurrence in this information with the appropriate symbol (® or ™), indicating US
registered or common law trademarks owned by IBM at the time this information was published. Such
trademarks may also be registered or common law trademarks in other countries. A current list of IBM
trademarks is available on the Web at http://www.ibm.com/legal/copytrade.shtml

The following terms are trademarks of the International Business Machines Corporation in the United States,
other countries, or both:
CICS® OS/390® System z9®
DB2® OS/400® System z®
DRDA® pureXML® WebSphere®
eServer™ Rational® z/OS®
i5/OS® Redbooks® z9®
IBM® Redpaper™ zSeries®
IMS™ Redbooks (logo) ®
Language Environment® System z10™

The following terms are trademarks of other companies:

Interchange, and the Shadowman logo are trademarks or registered trademarks of Red Hat, Inc. in the U.S.
and other countries.

Java, and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other
countries, or both.

Windows, and the Windows logo are trademarks of Microsoft Corporation in the United States, other
countries, or both.

UNIX is a registered trademark of The Open Group in the United States and other countries.

Linux is a trademark of Linus Torvalds in the United States, other countries, or both.

Other company, product, or service names may be trademarks or service marks of others.

xvi XML Processing Options on z/OS


Preface

XML plays an increasingly important part in today’s business automation systems.


Service-oriented architecture (SOA), enterprise service bus (ESB) and other modern
architectures all build upon XML. Each year more industries migrate their data-exchange
applications to XML and XML-based formats. XML continues to be one of the most pervasive
and successful technologies for the new millennium.

This IBM® Redbooks publication presents a broad perspective of the XML processing
capabilities of z/OS® . It begins with a high level view of the IBM products currently
implementing XML-specific features. It covers common design patterns and the products that
use them. It provides an overview and in-depth coverage of the two primary XML activities:
򐂰 Generating valid XML
򐂰 Parsing XML

It discusses where and how XML data can be stored.

The authors have included examples of simple and complex procedures, all of which have
been tested. They have included cautions and alternatives for common issues and pitfalls.

This book is helpful to anyone trying to learn about the various IBM products that provide
XML-oriented services and how they fit into existing applications. It is also valuable to
developers needing to gauge the pros and cons of the ways of generating and consuming
XML. It provides working examples to those needing a fast path to coding XML applications.

The team who wrote this book


This book was produced by a team of specialists from around the world working at the
International Technical Support Organization, Poughkeepsie Center.

Mike Ebbers is a Consulting IT Specialist and an ITSO project leader. He has worked for IBM
since 1974, mostly on mainframe systems, and has been with the ITSO since 1994. He
produces Redbooks and educational materials on a wide variety of topics.

Mogens Conrad is an IT Architect working for IBM Denmark. He has more than 30 years of
experience working with different types of mainframes, primarily for the financial industry. His
areas of expertise includes CICS®, DB2®, MQ, Business Continuity and Infrastructure. He is
member of CAF, CICS Architectural Forum.

Hans-Dieter Mertiens is a Senior IT Specialist in Germany. He works for Technical Sales


Support of the Server and Technology Group. He worked at several IBM installations before
joining IBM in 1984. After working several years in the area of special networking products he
joined the mainframe technical support group in 1991.Since then he has worked in the area of
new functions of MVS, OS/390®, and z/OS. He concentrated on how to bring new
applications onto the mainframe, and how they can interact with other applications and data
already available on the mainframe. In 2000 he started to support Linux®. He supports
several Linux installations in Germany, His main area of work is server consolidation on Linux
for System z®. He has participated in several residencies dealing with z/OS UNIX®, OS/390,
z/OS, and Linux at the ITSO Centers in Poughkeepsie and Raleigh. He holds a diploma in
physics from the University of Hamburg.

© Copyright IBM Corp. 2009. All rights reserved. xvii


Nagesh Subrahmanyam is an Advisory System Analyst with IBM India. He has over 8 years
of experience in the IT industry as an application programmer. He started with the z/OS
mainframe and over time has handled open systems technologies as well. His predominant
skills are with System z. He is always keen on trying open source code on the System z. He
holds a Mechanical Engineering degree from NIT Jamshedpur.

Michael Todd is a Application Architect with DST Systems, Inc. in Kansas City, Missouri,
U.S.A. He has 34 years of experience in a variety of computing related fields including 19
years with IBM mainframes. His areas of expertise include financial applications and real-time
process control systems.

Figure 1 The XML team: Mike Todd, Mogens Conrad, Hans-Dieter Mertiens, Nagesh Subrahmanyam, Mike Ebbers

Special thanks to the following people for their assistance and reviews:

Joseph Bostian
Matthew Cousens
Chris Larsson
Stephen Dulin
Bill Carey
IBM Systems & Technology Group, System z Software, Poughkeepsie NY

Thanks to the following reviewers:

David Cargill
Susan Malaika
Jane Man
Gary Mazo
Tom Ross
Christian Strauer

Thanks to the following people for their contributions to this project:

Bob Haimowitz
International Technical Support Organization, Poughkeepsie Center

Susann Thomas
IBM Application Integration & Middleware Solutions Specialist, Germany

Peter Elderon
IBM Software Group, Rational® PL/I Compilers and Architecture Software Architect

xviii XML Processing Options on z/OS


Become a published author
Join us for a two- to six-week residency program! Help write a book dealing with specific
products or solutions, while getting hands-on experience with leading-edge technologies. You
will have the opportunity to team with IBM technical professionals, Business Partners, and
Clients.

Your efforts will help increase product acceptance and customer satisfaction. As a bonus, you
will develop a network of contacts in IBM development labs, and increase your productivity
and marketability.

Find out more about the residency program, browse the residency index, and apply online at:
ibm.com/redbooks/residencies.html

Comments welcome
Your comments are important to us!

We want our books to be as helpful as possible. Send us your comments about this book or
other IBM Redbooks® publications in one of the following ways:
򐂰 Use the online Contact us review Redbooks form found at:
ibm.com/redbooks
򐂰 Send your comments in an e-mail to:
redbooks@us.ibm.com
򐂰 Mail your comments to:
IBM Corporation, International Technical Support Organization
Dept. HYTD Mail Station P099
2455 South Road
Poughkeepsie, NY 12601-5400

Preface xix
xx XML Processing Options on z/OS
1

Chapter 1. XML essentials


This chapter describes the basic concepts of XML used throughout this IBM Redbooks
publication. Our focus is on the System z environment using the z/OS operating system.

© Copyright IBM Corp. 2009. All rights reserved. 1


1.1 Introduction to XML
Extensible Markup Language (XML) is a simple, flexible text format that is designed to be
used in data interchange on the Web and in other electronic communications.

XML was developed in 1998 and is now widely used. It is one of the most flexible ways to
automate Web transactions. XML is derived as a subset from Standard Generalized Markup
Language (SGML) and is designed to be simple, concise, human readable, and relatively
easy to use in programs on different platforms. For more information about the XML standard,
see the following Web page:
http://www.w3.org/XML

As with other markup languages, XML is built using tags. Basic XML consists of start tags,
end tags, and a data value between the two. In XML you create your own tags, with a few
restrictions. Example 1-1 shows a simple XML document.

Example 1-1 Simple XML document


<?xml version="1.0" encoding="UTF-8" ?>
<Employee>
<ID>0000002150</ID>
<Lastname>SMITH</Lastname>
<Firstname>ROBERT</Firstname>
<Company>IBM</Company>
<Address>Bytoften 1</Address>
<Zipcode>8240</Zipcode>
<City>Risskov</City>
<Country>Denmark</Country>
</Employee>

While the XML syntax is simple, it is difficult to parse and transform an XML document into a
form that is usable to programming languages. Therefore, it is essential to have access to
efficient parsing and transformation tools.

XML contains document type and schema definitions. These are used to specify semantics
(allowable grammar) for an XML document. We discuss these next.

1.1.1 DTD
A document type definition, or DTD specifies the kinds of tags that can be included in your
XML document, the valid arrangements of those tags, and the structure of the XML
document. The DTD defines the type of elements, attributes, and entities allowed in the
documents, and can also specify some limitations to their arrangement. You use a DTD to
ensure you do not create an invalid XML structure. The DTD defines how elements relate to
one another within the document’s tree structure. You can also use it to define which
attributes can be used to define an element and which are not allowed. In other words, a DTD
defines your own language for a specific application.

The DTD can be stored in a separate file or embedded within the same XML file. If it is stored
in a separate file, it might be shared with other documents.

XML documents referencing a DTD will contain a <!DOCTYPE> declaration, which either
contains the entire DTD declaration for an internal DTD, or specifies the location of an
external DTD.

2 XML Processing Options on z/OS


Example 1-2 and Example 1-3 illustrate the use of external and internal DTDs.

Example 1-2 External DTD


<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT AGENDA (PERSONA+)>
<!ELEMENT PERSONA (EMPRESA, CARGO, NOMBRE, TELEFONO1+,TELEFONO2*, EXT?)>
<!ELEMENT EMPRESA (#PCDATA)>
<!ELEMENT CARGO (#PCDATA)> Chapter 1, “XML essentials” on page 1
<!ELEMENT NOMBRE (#PCDATA)>
<!ELEMENT TELEFONO1 (#PCDATA)>
<!ELEMENT TELEFONO2 (#PCDATA)>
<!ELEMENT EXT (#PCDATA)>

Example 1-3 XML document with reference to external DTD


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE AGENDA SYSTEM "DTD_Agenda.dtd">
<AGENDA>
<PERSONA>
<EMPRESA>Matutano</EMPRESA>
<CARGO>Gerente</CARGO>
<NOMBRE>Pepe Montilla</NOMBRE>
<TELEFONO1>912563652</TELEFONO1>
<TELEFONO2>658968574</TELEFONO2>
<EXT>256</EXT>
</PERSONA>
</AGENDA>

In Example 1-4 we have the same XML document, but the DTD declaration is included in the
document

Example 1-4 XML document with internal DTD


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE AGENDA [
<!ELEMENT AGENDA (PERSONA+)>
<!ELEMENT PERSONA (EMPRESA, CARGO, NOMBRE, TELEFONO1+,TELEFONO2*, EXT?)>
<!ELEMENT EMPRESA (#PCDATA)>
<!ELEMENT CARGO (#PCDATA)>
<!ELEMENT NOMBRE (#PCDATA)>
<!ELEMENT TELEFONO1 (#PCDATA)>
<!ELEMENT TELEFONO2 (#PCDATA)>
<!ELEMENT EXT (#PCDATA)>
]>
<AGENDA>
<PERSONA>
<EMPRESA>Matutano</EMPRESA>
<CARGO>Gerente</CARGO>
<NOMBRE>Pepe Montilla</NOMBRE>
<TELEFONO1>912563652</TELEFONO1>
<TELEFONO2>658968574</TELEFONO2>
<EXT>256</EXT>
</PERSONA>
</AGENDA>

Chapter 1. XML essentials 3


1.2 XML schema definition
Because DTDs have some limitations, the concept of schemas was created. Schemas
provide a number of advantages over DTDs. The most important are:
򐂰 Schemas use XML syntax.
򐂰 It is possible to specify data types and data values.
򐂰 Schemas are extensible.
򐂰 Schemas are able to handle namespaces (see 1.3, “Namespaces” on page 6).

It is difficult to give a general outline of the elements of a schema, due to the large number of
elements that can be used. The purpose of the W3C XML Schema Definition Language is to
provide an inventory of XML markup constructs with which to write schemas. Example 1-5 is
a simple document that describes the information about a book. Throughout this book,
references to schemas are to W3C definitions of a schema.

Example 1-5 XML Document


<?xml version="1.0" encoding="UTF-8"?>
<book isbn="0836217462">
<title>
Don Quijote de la Mancha
</title>
<author>De Cervantes Saavedra, Miguel</author>
<character>
<name>Sancho Panza</name>
<friend-of>El Quijote</friend-of>
<since>1547-10-04</since>
<qualification> escudero </qualification>
</character>
<character>
<name>ElbaBeuno</name>
<since>1547-08-22</since>
<qualification>Amor Platonico de Don Quijote</qualification>
</character>
</book>

Because the XML Schema is a language, there are several options to build a possible
schema that covers the XML document. Example 1-6 is a simple and feasible design.

Example 1-6 Corresponding Schema


<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="book">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="author" type="xsd:string"/>
<xsd:element name="character" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="friend-of" type="xsd:string" minOccurs="0"
maxOccurs="unbounded"/>
<xsd:element name="since" type="xsd:date"/>

4 XML Processing Options on z/OS


<xsd:element name="qualification" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="isbn" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
</xsd:schema>

It is clear that Example 1-6 on page 4 is an XML document because it begins with an XML
document declaration. The schema element opens our schema that contains the definition of
the schema namespace. Then we define an element named “book.” This is the root element
in the XML document. We decided it is a complex type because it has attributes and non-text
children. We begin to declare the children elements of the root element book. W3C XML
Schema lets us define the type of data, as well as the number of possible occurrences of an
element. For more information about possible values for these types, refer to the specification
documents from W3C. The schema URLs are:
򐂰 http://www.w3.org/TR/xmlschema-1/
򐂰 http://www.w3.org/TR/xmlschema-2/

In the schema shown in Example 1-6 on page 4, a namespace declaration contains a


namespace prefix and a namespace identifier. The namespace identifier is sometimes the
URL for the relevant namespace specification document. The XML namespace
recommendation requires only that the specification be unique and persistent. It does not
require the declaration contain a valid URI/URL or that the URI/URL point to an actual
document or schema. Each element in the schema has the prefix “xsd:”. This is a normal
namespace prefix. See 1.3, “Namespaces” on page 6. Any prefix is legal, but for clarity it is
normal to use xsd: or xs: to denote the XML schema namespace.

1.2.1 XML schema options


XML Schema Language offers possibilities and alternatives beyond what we show in
Example 1-6 on page 4. We could develop another schema based on a flat catalog of all the
elements available in the instance document. For each of those, we could make lists of child
elements and attributes. Thus we would have two choices: defining elements and attributes
as they are needed, or creating them first and later referencing them. The first option has a
significant disadvantage because the schema can become difficult to read and maintain when
documents are complex.

W3C XML Schema allows us to define data types and use these types to define our attributes
and elements. It also allows the definition of groups of elements and attributes. In addition,
there are several ways to arrange relationships between elements.

Documentation for XML schemas can be defined by the xsd:documentation element, and
processing instructions for applications can be included with the xsd:appinfo element. More
details are available on the Web at the following Web page:
http://www.w3.org/TR/NOTE-xml-schema-req

1.2.2 xsd
xsd is used both as an acronym for an XML schema definition (also called xsd schema or
simply schema) and as the file extension for files containing XML schema definitions.

Chapter 1. XML essentials 5


1.3 Namespaces
Namespaces are used when there is a need to have different elements, possibly with different
attributes, but with the same name. Depending upon the context, a tag is related to one
specific element or to another specific element. Without namespaces, it would be impossible
to specify the context to which an element belongs. Example 1-7 illustrates this situation.

Example 1-7 XML document with duplicated element names


<?xml version="1.0" ?>
<book>
<title>XML Sample</title>
<pages>210</pages>
<isbn>1-868640-34-2</isbn>
<author>
<firstname>JuanJose</firstname>
<lastname>Hernandez</lastname>
<title>Mr</title>
</author>
</book>

Clearly there is a problem with the element <title>. It appears here in two different contexts.
This situation complicates things for processors and might cause ambiguities. We need a
mechanism to distinguish between the two and apply the correct semantic description to the
each tag. The cause of this problem is that this document uses only one common name
space.

The solution to this problem is namespaces. Namespaces are a simple and straightforward
way to distinguish names used in XML documents. By providing the related namespace when
an element is being validated, the problem is solved.

Example 1-8 XML document using namespace prefixes


<?xml version="1.0" ?>
<library-entry xmlns:authr="http://sc58ts.itso.ibm.com/Jose/2002/author.dtd"
xmlns:bk="books.dtd">
<bk:book>
<bk:title>XML Sample</bk:title>
<bk:pages>210</bk:pages>
<bk:isbn>1-868640-34-2</bk:isbn>
<authr:author>
<authr:firstname>JuanJose</authr:firstname>
<authr:lastname>Hernandez</authr:lastname>
<authr:title>Mr</authr:title>
</authr:author>
</bk:book>
</library-entry>

As you can see in Example 1-8, the <title> tag is used twice, but in different contexts: within
the <author> element and within the <book> element. Note the use of the xmlns keyword in
the namespace declaration.

After a prefix is defined on an element it can then be used by all descendants of that element.
In Example 1-8, we specified the relevant namespace prefix before each element to illustrate
the relationship of each element to a given namespace. However, if the prefix is not specified,
the element will be in the default namespace if one has been specified or in no namespace if

6 XML Processing Options on z/OS


there is no default namespace. A default namespace is one that is defined on an element with
the xmlns attribute without specifying a prefix.

Example 1-9 is similar to Example 1-8 on page 6, but it uses default namespaces to produce
the same namespace relationships.

Example 1-9 XML document using default namespaces


<?xml version="1.0" ?>
<library-entry>
<book xmlns="books.dtd">
<title>XML Sample</title>
<pages>210</pages>
<isbn>1-868640-34-2</isbn>
<author xmlns="http://sc58ts.itso.ibm.com/Jose/2002/author.dtd">
<firstname>JuanJose</firstname>
<lastname>Hernandez</lastname>
<title>Mr</title>
</author>
</book>
</library-entry>

For more information about namespaces, refer to the following Web page:
http://www.w3.org/TR/REC-xml-names

The namespace is defined using a Namespace declaration. In Example 1-10 you see the
namespace declarations from the previous example.

Example 1-10 XML Namespace declarations


xmlns:authr="http://sc58ts.itso.ibm.com/Jose/2002/author.dtd"
xmlns:bk="books.dtd"

A namespace is declared using the attribute xmlns, followed by the namespace prefix (here
authr and bk). The namespace declaration is given a value to further identify the declaration.
The namespace value must be an IRI or URI identifier, but the value is only used as a unique
string. It can point to existing files or Web sites but will not reference those files.

1.4 Encoding
Document encoding refers to the character scheme used to create document content. The
XML standard requires that, by default, XML documents be created using one of three
Unicode character sets. However, you can use any character set you like, so long as the XML
declaration at the beginning of the document declares the character set used. This is done by
providing an encoding= declaration. It is essential that the encoding declaration provide a
name that sending and receiving programs understand and upon who’s meaning they agree.

Because Unicode is the default encoding, many parsers handle Unicode XML documents.
However, if you are certain all documents delivered to an application will be in EBCDIC-only
or ASCII-only, using an EBCDIC-only or ASCII-only parser is acceptable. Keep in mind that
there are many EBCDIC character sets, not just one. There are many ASCII character sets as
well. Consequently, it is of paramount importance that parsers be able to discern which
character set encoding was used to create the document.

Chapter 1. XML essentials 7


For Unicode documents, parsers can discern the character encoding by looking at the
document content. It might sound like a contradiction that the parser has to read the
document to get the encoding definition before the parser knows how to read the document.
This is implemented within the parsers by reading the first few characters of the document
and determining the document’s encoding scheme from those few characters. From the first
bytes of the XML document the parser can determine if the encoding is EBCDIC, ASCII, or
UTF. With this information the parser can read the encoding phrase and get the specific
encoding variant.

Unicode documents can (but are not required to) include an encoding declaration such as in
Example 1-11.

Example 1-11 XML Encoding Declaration for Unicode


<?xml version="1.0" encoding="utf-8"?>

To enable the parser to recognize the encoding of a non-unicode document, the XML
declaration at the start of the document must include an encoding= definition. Example 1-12
shows the encoding declaration for some common EBCDIC character sets.

Example 1-12 XML Encoding Declarations for EBCDIC


<?xml version="1.0" encoding="IBM-037"?>
<?xml version="1.0" encoding="IBM-1140"?>
<?xml version="1.0" encoding="IBM-1047"?>
<?xml version="1.0" encoding="IBM-500"?>

The subject of character encoding and how to determine a document’s encoding is broad
enough to merit an entire chapter. See Chapter 11, “XML and character encoding issues” on
page 145 for more details regarding document encoding.

1.5 XML 1.0 and XML 1.1


The basic XML definitions (XML 1.0) were defined in 1998 by a W3C recommendation. This
definition was later revised and the current version of XML 1.0 is fifth edition from 2008. See
the entire definition of XML 1.0 fifth edition at:
http://www.w3.org/TR/2008/REC-xml-20081126/

XML 1.1 was first published in 2004, and the current version of XML 1.1 is a second edition
from 2006. Read more about the XML 1.1 second edition at:
http://www.w3.org/TR/2006/REC-xml11-20060816/

The two current versions of XML (XML 1.0 fifth edition and XML 1.1 second edition) are
nearly identical, but XML 1.1 allows a wider range of characters to be used in data and
attribute values.

For mainframe developers it is important to know that XML 1.1 allows the mainframe
end-of-line character (NEL). While some operating systems use carriage return (CR) as the
end-of-line terminator, others use line feed (LF) or CR with LF. z/OS UNIX uses the new line
(NEL) character. Inclusion of the NEL character as a valid whitespace character means that
XML documents created on the mainframe can be parsed on any platform supporting XML
1.1 without first converting the NEL characters to CR or LF.

8 XML Processing Options on z/OS


1.6 XML processing
One of the main topics of parsing XML is the requirement that the XML documents conform to
the XML language rules. There are two levels of requirements regarding XML documents:
򐂰 Well-formed: The XML document must obey the XML syntax.
򐂰 Validated: The XML document must be well-formed and respect the rules defined in the
corresponding schema.

1.6.1 Well-formedness
To be well-formed, documents must conform to the basic rules for XML documents. Table 1-1
lists a subset of the requirements for a well-formed XML document.

Table 1-1 Well-formed XML documents


Requirement Not Well-formed Example Well-formed Example

The document has exactly one <element1>value1</element1> <element0>


root element <element2>value2</element2> <elem1>value1</elem1>
<elem2>value2</elem2>
</element0>

Each start tag is matched by one <elem1> <elem1>


end tag <elem2>value2 <elem2>value2</elem2>
</elem1> </elem1>

All elements are properly nested <elem1> <elem1>


<elem2>value2</elem1> <elem2>value2</elem2>
</elem2> </elem1>

Attribute values are quoted <elem1 id=15>value1</elem1> <elem1 id=”15”>value1</elem1>

Disallowed characters are not <elem1> 123<456</elem1> <elem1> 123&lt;456</elem1>


used in tags or values (Note 1)

About Table 1-1: A binary zero (null) character is not part of well-formed XML. Binary
zeroes can interfere with parsing of documents in unexpected ways. For example, if you
generate or copy an XML document into a variable, and the variable contained null
characters before the generate/copy, there might be nulls following your document. Even
though you might think these nulls are not part of your document, the parser would give
you an error anyway.

1.6.2 Validation
The process of checking to see if an XML document conforms to a schema or DTD is called
validation. This is in addition to checking a document for compliance to XML's core concept
of syntactic well-formedness. All XML documents must be well-formed, but it is not required
that a document be valid unless the XML parser is validating. When validating, the document
is also checked for conformance with its associated schema.

Chapter 1. XML essentials 9


Documents are only considered valid if they satisfy the requirements of the DTD or schema
with which they have been associated. These requirements typically include such constraints
as:
򐂰 Elements and attributes that must or might be included, and their permitted structure.
򐂰 The structure is specified by a regular expression syntax.
򐂰 How character data is to be interpreted, for example as a number, a date, or a color, and
so on.

XML document validations can be performed using specialized parsers.

1.7 Industry formats


With the development of XML schemas, different industries started to define standards for
using XML in data communication, and today there are many standard XML schemas
available. Table 1-2 lists a few of these schemas.

Table 1-2 Standard XML schemas


Name description Industry

AMBER Alert Message Schema Justice

COLLADA COLLAborative Design Activity IT


3D Asset Exchange Schema Games
Graphics

FIXML Financial Information Exchange Financial

IFX Interactive Financial eXchange Financial

OTA Open Travel Alliance Travel

SEPA Single Euro Payments Area Financial

UBL Universal Business Language B2B

1.8 XML parsing


Parsing XML is the process of breaking the text into usable pieces (for example, finding the
value associated with a particular element). There are several approaches to parsing. The
most common are SAX and DOM.

1.8.1 SAX: Simple API for XML


SAX is an event-driven interface. The document is read serially and its contents are reported
as callbacks to a handler routine or object. This is sometimes called push processing. The
current version is SAX 2.0.1. SAX was originally a Java implementation. SAX 2 has been
implemented in Java and other languages.

10 XML Processing Options on z/OS


1.8.2 DOM: Document Object Model
DOM is an API that allows navigation of the entire document by representing the contents of
the document in a tree-like configuration. The DOM tree is built in main storage and kept there
through the entire parsing process. For large XML documents, storage constraints might be a
problem. so SAX parsing would be used as an alternative.

1.8.3 Less common parsing methods


STaX (Streaming API for XML) is a cursor-oriented approach. The application moves the
cursor forward, pulling the information from the parser as it is needed.

Non-extractive parsing has the goal of overcoming the limitations of DOM and SAX.
VTD-XML is an example of non-extractive XML parsing.

Data binding is a form of XML processing where data is made available as a hierarchy of
custom, strongly typed classes.

1.9 XML Transformation


Today we have a number of tools to manipulate XML documents. Some of the most important
are XPath, XQuery, XPointer, and XSLT.
򐂰 XPath, the XML Path Language
This is a query language designed for selecting nodes and extracting information from
XML documents. Find more information in the official recommendations:
http://www.w3.org/TR/xpath
򐂰 XQuery, the XML Query Language
This provides the means to extract and manipulate data from XML documents. One
example is to extract information from several XML documents and form summary report.
See detailed information at:
http://www.w3.org/TR/xquery
򐂰 Xpointer, the XML Pointer Language
This is a system for addressing XML elements in a XML document. More information to be
found at the following Web pages:
– http://www.w3.org/TR/REC-xptr-element-20030325/
– http://www.w3.org/TR/REC-xptr-framework-20030325/
򐂰 XSLT, the XSL Transformation language
This is an XML-based language used for transforming XML documents into other types of
XML, such as HTML, XML, or plain text. The transformation is described in XSL, XML
Stylesheet Language. The XSL stylesheet is in itself a XML document. Read more about
XSLT at the following Web page:
http://www.w3.org/TR/xsl/

Chapter 1. XML essentials 11


Example 1-13 shows how you can use XSLT to generate a HTML document from a XML
document.

Example 1-13 XSLT stylesheet


<?xml version="1.0" encoding="ibm-1047-s390" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns="http://www.w3.org/1999/xhtml">
<xsl:template match="Employee">
<html>
<head>
<h2>Employee details</h2>
</head>
<body bgcolor="#ffffff">
<table>
<tr>
<td>ID</td>
<td><xsl:apply-templates select="ID"/></td>
</tr>
<tr>
<td>FirstName</td>
<td><xsl:apply-templates select="Firstname"/></td>
</tr>
<tr>
<td>LastName</td>
<td><xsl:apply-templates select="Lastname"/></td>
</tr>
<tr>
<td>Company</td>
<td><xsl:apply-templates select="Company"/></td>
</tr>
<tr>
<td>Address</td>
<td><xsl:apply-templates select="Address"/></td>
</tr>
<tr>
<td>Address</td>
<td><xsl:apply-templates select="Zipcode"/></td>
<td><xsl:apply-templates select="City"/></td>
</tr>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

A stylesheet converts the XML in Example 1-1 on page 2 to an HTML page. The stylesheet
selects some of the elements in the XML document, discards others, and adds the necessary
text to make the result a legal HTML document. See Figure 1-1 on page 13.

12 XML Processing Options on z/OS


Figure 1-1 XML from Example 1-1 on page 2 transformed to HTML using XSLT stylesheet

Chapter 1. XML essentials 13


14 XML Processing Options on z/OS
2

Chapter 2. Overview of XML processing on


System z
XML can be generated and consumed in a number of System z-hosted application
environments using a variety of programming languages. This chapter provides an overview
of the applicable environments and products. The specific capabilities, advantages, and
disadvantages of these options are covered in Chapter 7, “Processing components,
relationships, and options” on page 85.

© Copyright IBM Corp. 2009. All rights reserved. 15


2.1 z/OS XML System Services
z/OS V1R8 introduced direct support for XML parsing with z/OS XML System Services. z/OS
XML System Services is an integral part of the z/OS operating system and was designed to
provide XML parsing assistance with minimal path-length. From the application perspective,
z/OS XML System Services is a set of callable routines that parse (or validate and parse) an
XML document, rendering its contents into an intermediate format that is easily navigated.
Applications can focus on business processing and rely upon z/OS XML System Services to
handle the intricacies of atomizing an XML document.

z/OS XML Systems Services does not use or provide SAX or DOM interfaces. It is a
buffer-oriented interface that allows the input XML to be provided in pieces and the parsed
result to be consumed in pieces. There is no limit on document size using this approach.
Documents of many gigabytes can be processed.

While z/OS XML System Services does not provide SAX or DOM interfaces, the intermediate
format produced by z/OS XML System Services can be used to support SAX and DOM
parsers as well as non-traditional parsing requirements.

A number of XML-enabled products for System z use z/OS XML System Services behind the
scenes to gain advantage from its high-performance and consistent parsing results. For
example, COBOL and PL/I provide the option of using z/OS XML System Services. DB2
PureXML support also uses z/OS XML System Services for some of its XML processing.
z/OS XML provides the option to offload most of the XML parsing to a zAAP or zIIP specialty
engine, when present.

An illustration and description of the returned XML parsed data stream is available in 6.1.1,
“Parsed XML data stream” on page 67.

2.2 XML Toolkit for z/OS


The XML Toolkit is comprised of two main components:
򐂰 XML Toolkit Parser, C++ Edition for parsing
򐂰 XML Toolkit XSLT Processor C++ Edition for transformations

The XML Toolkit Parser is an implementation of the IBM XML4C parser. XML4C is based
upon open source code from the Xerces Apache project of the Apache Software Foundation.
The Toolkit Parser allows C++ applications to parse XML documents using either the DOM or
SAX 2.0 interfaces. Some C++ programming experience is required to use the Toolkit Parser,
C++ Edition.

The Toolkit Parser, C++ Edition provides document validation against an XML schema or
DTD as well as just doing non-validating or well-formedness checking. The Toolkit parser
provides the option (using special classes) of using z/OS XML System Services to perform
the parsing without validation or parsing with validation (XML Schema validation only). This
provides the option to offload most of the XML parsing to a zAAP specialty engine when
present.

One unique aspect of the XML Toolkit for z/OS parser is that it always returns the parsed
names and values in UTF-16 regardless of the character encoding of source XML. This might
require customization of the invoking programs.

16 XML Processing Options on z/OS


The XML Toolkit XSLT Processor, C++ Edition provides an implementation of the IBM
XSLT4C XSLT processor. XSLT4C is based on Apache’s Xalan XSLT processor. It
implements the W3C recommendations for XSL Transformations Version 1.0 and XML Path
Language Version 1.0. This feature provides XML to XML, XML to HTML, and XML to text
transformation capabilities.

C++ classes can also be used to generate XML streams.

XML Toolkit
HTML or text
for z/OS
XSLT
XML
processor XML

XSLT XML ToolKit parser


z/OS XML System Services

C++ SAX
XML XML ToolKit parser
application
z/OS XML System Services

XML C++ DOM XML Toolkit parser


application
z/OS XML System Services

Figure 2-1 XML Toolkit for z/OS architecture

2.3 Enterprise COBOL for z/OS


Enterprise COBOL for z/OS provides COBOL language statements for generating and
parsing XML.

2.3.1 COBOL XML generation


Enterprise COBOL for z/OS V3R3 introduced a new XML GENERATE statement. Enterprise
COBOL V4R1 enhanced XML generation from COBOL data structures by adding support for
namespaces. XML GENERATE is a simple means for generating valid XML streams or
documents from COBOL data structures. The data structures can be simple single-level
structures to complex, multi-level, multi-dimensional structures. XML supports data
configurations for which there is no matching COBOL data layout. Therefore, not every
conceivable XML configuration can be easily produced by COBOL. However, using multiple
invocations of XML GENERATE, virtually any document structure can be created.

Chapter 2. Overview of XML processing on System z 17


2.3.2 COBOL XML parsing
Enterprise COBOL V3R1 introduced a SAX parsing model within conventional COBOL
programs through a new XML PARSE statement. XML PARSE in Enterprise COBOL Version
3 does not perform document validation but does perform some well-formedness checking.
Enterprise COBOL for z/OS V4R2 does support parsing with validation by using the latest
version of the z/OS XML System Services Parser. See 6.4, “Newer features to handle XML on
z/OS” on page 81 for additional information regarding COBOL parsing with validation. Users
can exploit the zAAP with XML PARSE in Enterprise COBOL V4 when the
XMLPARSE(XMLSS) options are in effect.

As a SAX-like parser, application developers provide a document event handling routine


(handler or callback routine) that is automatically driven for each XML document event.
Document events are XML fragments such as begin tag, end tag, element value, attribute
name, attribute value, processing instruction, and C-data. As each fragment is isolated and
categorized, the corresponding event is generated by the parser and subsequently handled
by the provided event handling routine.

COBOL programs can acquire XML documents from numerous sources (sequential files, MQ
messages, HTTP requests), use the XML PARSE statement to parse the XML document into
COBOL data structures, and then process those data structures.

It is also possible to invoke the z/OS XML Toolkit XSLT processor from COBOL. You can also
invoke the XML Toolkit for z/OS Parser from COBOL, but some glue code is recommended to
deal with differences between the C and COBOL run-time error handling semantics. There is
an example of this glue code within XML Toolkit for z/OS User’s Guide, SA22-7932.

Enterprise COBOL Version 4


XML PARSE CALL CALL CALL

COBOL z/OS XML z/OS XML


C glue code C glue code
native XML System System
Parser Services Services
Parser Parser

XML Toolkit XML Toolkit


for z/OS XSLT for z/OS
Processor Parser C++
C++ Edition Edition

Figure 2-2 Parsing architecture for Enterprise COBOL

18 XML Processing Options on z/OS


2.4 Enterprise PL/I for z/OS
Enterprise PL/I for z/OS provides a built-in function for XML generation and three built-in
routines for parsing.

2.4.1 PL/I XML generation


Enterprise PL/I for z/OS V3R3 introduced the XMLCHAR built-in function. This function
generates an element-style XML stream from a native PL/I data structure.

2.4.2 PL/I XML parsing


Enterprise PL/I for z/OS provides three built-in subroutines for SAX-based non-validating
parsing, though checks for well-formedness are performed. PLSIAXA and PLISAXB were
introduced with V3R1, and PLISAXC was introduced with V3R8.

PLISAXA parses documents where the entire document is available in memory. PLISAXB
parses documents where the entire document is available within a file. PLISAXB limits the
document size to less than 2 GB. Additionally, PLISAXB copies the entire document file into
memory before parsing. Therefore, sufficient memory must be available to the task to perform
that file-to-memory copy.

PLISAXC provides parsing using XML System Services and parses documents available in
one or more buffers. PLISAXC is the only PL/I built-in XML parsing subroutine which provides
the ability to offload most of the parsing work to a zAAP.

PL/I applications can also invoke z/OS XML System Services directly. This might be required
to access parsing functionality which is not available through the language’s parser interface.

It is also possible to invoke the z/OS XML Toolkit XSLT processor from PL/I. You can also
invoke the XML Toolkit for z/OS Parser from PL/I, but some glue code is recommended to
deal with differences between the C and PL/I run-time error handling semantics. There is an
example of the glue code and COBOL calling the glue code within the XML Toolkit for z/OS
User’s Guide, SA22-7932.

PL/I

PLISAXA PLISAXB PLISAXC z/OS XML XML Toolkit C glue code


XML XML XML System XSLT
Parser Parser Parser Services Processor
C++ Edition

XML Toolkit
Parser C++
z/OS XML Edition
System
Services

Figure 2-3 PL/I and z/OS XML System Services

Chapter 2. Overview of XML processing on System z 19


2.5 CICS Transaction Server for z/OS
CICS can generate and parse XML in two ways:
򐂰 Using the EXEC CICS TRANSFORM statement
From CICS TS 4.1 the new EXEC CICS TRANSFORM statement enables you to generate
or parse XML regardless of the communications channels.
򐂰 Using CICS WebServices
The CICS WEB Services functions within CICS TS break an HTTP request into HTTP,
SOAP, and XML components.

Both methods require you prepare the parsing or generation using the CICS WebServices
Assistant or RD/z to generate conversion modules.

CICS Web Services can process and respond to incoming SOAP requests. In addition, it can
issue SOAP requests to—and process the SOAP responses from—other Web Services.
SOAP data structures are built upon XML and require XML parsing. SOAP requests and
responses often contain application provided data in XML format.

CICS has the ability to parse and preserve binary data within XML with the XML-binary
optimization Packaging (XOP) specification for XML and SOAP Message Transmission
Optimization Mechanism (MTOM) specification for SOAP.

Support for CICS Web Services pipeline is available beginning in V4R1 using z/OS XML
System Services for their on-demand parsing.

CICS uses the XML Toolkit to enable Web Services Security.

Application SOAP message

CICS TS V3R1 CICS TS V4R1


Web Services Security

CICS z/OS XML XML


Integrated System Toolkit
Parsing Services for z/OS
Parser
Figure 2-4 CICS Transaction Server XML architecture

20 XML Processing Options on z/OS


2.6 IMS XML DB
The IMS™ XML DB component of the IMS SOA Integration Suite allows IMS Java
applications to store and retrieve XML data directly within an IMS database. Alternatively, IMS
Java applications can shred XML strings into native IMS data types and transform native IMS
data into valid XML strings.

Business processes where the primary use of XML data will be Java applications that also
use IMS might benefit from IMS XML DB when integrating new XML processing requirements
within existing IMS applications. See Figure 2-5.

XML Schema
IMS DBD
book

@year seq PCB: BIB21


BOOK
xs:date YEAR TITLE PUBLISH PRICE
XML title choice publisher price
IMS
Documents xs:string xs:string xs:decimal
0:oo 0:oo
Data
AUTH EDIT
LAST FIRST LAST FIRST AFFL

author author

seq seq

last first last first affiliation

xs:string xs:string xs:string xs:string xs:string

Figure 2-5 IMS DB XML

2.7 Rational Developer for System z


Rational Developer for System z (RD/z) provides an Eclipse-based development environment
that brings together many of the tools required to develop and deploy Web-based services on
System z. XML converters are required run-time elements in some of these applications.
RD/z provides a modern interface that allows rapid development of XML converter routines.

RDz XML converters can be created from COBOL and PL/I applications in either bottom-up
mode (starting from an existing COBOL or PL/I data structure) or in a meet-in-the-middle
mode by mapping between existing XML schema or a WSDL file and an existing COBOL or
PL/I data structure. In the meet-in-the-middle mode, the latest RDz versions (in addition to
mapping XML elements) allow mapping of XML attributes or even a mixture of elements and
attributes. In a top-down mode, RDz integrates CICS-provided tooling that support CICS Web
services and CICS XML Transformation.

For both COBOL and PL/I, RDz can supply code that allows generation of XML documents
without requiring the use of XML GENERATE language. XML generation capabilities of the
code produced by RDz are also more flexible in that they allow for customization (such as
selective element omission or renaming of the default element names that are generated from
the data structure names).

RD/z can produce XML converters in either COBOL or PL/I. When COBOL is used, the option
to use z/OS XML System Services and offloading XML processing to a zAAP processor is
provided.

Chapter 2. Overview of XML processing on System z 21


The value of these tools is that there is NO XML parsing or XML generation code that the user
needs to write by hand. It supports versions of the COBOL compiler that do not have the XML
GENERATE capability (but it does require XML PARSE). It allows fine tuning on how
elements of the data structure are processed in the XML (omission, renaming, initialization).

2.8 Java-centric processing of XML


Numerous XML generation, parsing, and transformation classes are available for Java. Within
z/OS, all Java processing is eligible to run on zAAP processors. Java classes can run under
the following products:
򐂰 Native Java within z/OS UNIX
򐂰 WebSphere® Application Server
򐂰 WebSphere Message Broker
򐂰 WebSphere Process Server
򐂰 WebSphere Enterprise Service Bus (ESB)
򐂰 CICS TS can host native Java applications and Enterprise Java beans
򐂰 IMS can host native Java applications and Enterprise Java beans

WebSphere Application Server has the ability to parse and preserve binary XML content
through MTOM and XOP. Many WebSphere products have the ability to initiate SOA
processing using XML-based SOAP and REST protocols.

XML parsing using Java is currently distinct from other IBM XML-enabled products. Java XML
does not currently employ z/OS XML System Services, for example. But all Java processing
is offloadable to zAAP processors. Java employment of SAX, DOM, JDOM, JAXP, TrAX,
XPath, and XSLT are beyond the scope of this IBM Redbooks publication.

2.9 pureXML on DB2 9 for z/OS


DB2 9 for z/OS introduced pureXML® capabilities. DB2 can accept, validate, store, query,
and generate XML using SQL and XPath languages. DB2 can convert (shred) XML into
relational tables and transform query results into well-formed XML documents or fragments.
DB2 can directly query stored XML without converting to normalized, relational tables. XML
query results can be joined with traditional SQL results to provide seamless integration of
highly structured relational data with more flexible and sometimes less structured XML data.

Business processes where the primary use of XML data will be within applications that also
use SQL might realize significant synergy and savings by using DB2's pureXML capabilities.
pureXML can decrease the cost of development, deployment, maintenance, and support
when integrating new XML processing requirements within existing SQL/DB2-based
applications.

DB2 for z/OS transparently uses the capabilities of z/OS XML System Services for some of its
parsing. The portion of XML processing performed by z/OS XML can be directed to a zAAP or
a zIIP processor, depending on whether DB2 is executing in task or SRB mode, respectively.
Additionally, for distributed database requests, additional non-XML processing can be
directed to a zIIP processor.

22 XML Processing Options on z/OS


DB2 9
pureXML

XML Query

Relational Tables
XML Query

XML Join
results Query

standard query Native XML


results column
Query
XML
results

Figure 2-6 DB2 with pureXML

pureXML features are also available in DB2 for LUW. The many capabilities of pureXML are
not discussed in this book. For more information about pureXML, see the IBM Redbooks web
site at the following Web page:
http://www.redbooks.ibm.com

2.10 Linux for System z


Linux for System z might be included in application scenarios where XML data can be
handled on the Linux side of the mainframe. Linux works as an intermediary to an application
on z/OS and might perform some preselection based on an XML document. So there might
be a need to have support for XML strings on Linux also. We can see that there are few limits
to finding a desirable solution for a given task.

The Linux for System z environment provides no support for XML in the operating system
itself. However there are many packages available under Java or with programming
languages. Beginning with version 1.4, Java contains the API for XML Processing (JAXP). So
it contains also the SAX and DOM parsing interfaces. There is also Xerces available on Linux
so you can integrate SAX or DOM style parsing into a C++ program. The Apache Xerces
Project also provides packages for Java and Perl. Another package is libxml2, which supports
C and perl, another important programming language on Linux. Of course, a well-defined
strategy to use Open Source in your production environment is a key to successful
implementation.

There also are commercial products available that support XML on Linux for System z. These
include databases such as Tamino from Software AG and DB2 for Linux (including Linux on
System z. Other products deal with XML documents in the WebSphere family of products.

Chapter 2. Overview of XML processing on System z 23


24 XML Processing Options on z/OS
3

Chapter 3. XML sources, targets, and


design patterns
In this chapter we discuss the following topics:
򐂰 The means by which XML documents typically enter and leave System z
򐂰 Processing scenarios where XML is generated and consumed within System z
򐂰 The application environments that process, transform, store, and generate XML

© Copyright IBM Corp. 2009. All rights reserved. 25


3.1 Common points of Entry and Exit
In this section we describe four options for introducing and outputting XML.

3.1.1 XML documents as files


XML documents often appear on System z in the form of sequential files. The files might
reside within HFS or z/FS UNIX file systems, within native z/OS sequential files,
PDS/PDSE/GDG members, and with VSAM ESDS, KSDS, and RRDS files. XML documents
might also appear as in-stream data to a job step.

Files can be created by FTP and other file transmission methods, traditional batch jobs, and
newer workloads such as native batch Java, WebSphere Application Server applications,
WebSphere Message Broker, WebShere Process Server, and applications running under
z/OS UNIX. XML document files are not always newly created files. Configuration information
is a common use for permanent XML documents that are parsed at regular intervals such as
every application startup.

Generated XML is often stored within sequential data sets until they are transmitted or copied
to an external media such as tape or CD. XML might also appear as stream-out or SYSOUT
data from a job step.

3.1.2 Messaging transports


Java JMS and WebSphere MQ Messaging are often used as transports to deliver application
requests and responses that contain XML. All three common messaging design patterns
benefit from the flexible and self-describing nature of XML:
򐂰 request-reply
򐂰 send-and-forget
򐂰 publish-subscribe

Messaging for request-reply and publish-subscribe are common exit points on System z.
System z can be the sender or receiver in a send-and-forget application.

3.1.3 Web services through HTTP/SOAP requests


HTTP and SOAP requests often contain XML data beyond the basic protocol elements.
Requests might originate within a external B2B application, an internal application or even in
a browser.

System z is now a frequent consumer of SOA and Web services. In these scenarios, XML
exiting System z with no corresponding input request has become commonplace.

3.1.4 Generated and consumed on z


There are numerous scenarios where XML is generated and consumed without ever leaving
System z. The following partial list of applications details which commonly exchange
information through XML:
򐂰 Enterprise service bus applications, such as WebSphere ESB
򐂰 Applications interconnected using SOA
򐂰 Web services employing CICS, DB2 or IMS applications

26 XML Processing Options on z/OS


Java-friendly environments such as WebSphere Application Server, WebSphere Message
Broker and WebSphere Process Server rely heavily upon XML-based data storage and
messaging.

Traditional batch jobs can generate XML in one or more steps and consume it in other steps.

3.2 XML processing models


In this section we describe nine processing methods for consuming and generating XML.

It is important to recognize that z/OS XML System Services is being used by new IBM and
third-party products every day. Even if a processing model discussed here does not use z/OS
XML System Services today, it might do so soon.

3.2.1 File triggered batch jobs


Many installations have the capability to submit a batch job to JES2/JES3 for execution when
a file is created whose name matches specific criteria. When the triggering file contains XML,
all of the following design patterns are feasible:
򐂰 The application program uses the XML Toolkit XSLT processor to read, parse, and
transform the document file into traditional sequential, record oriented files for processing
by traditional batch jobs and programs.
򐂰 The job executes a C++ program that uses the XML Toolkit Parser, which parses and
processes the XML document file, producing XML output, traditional sequential file output,
or both. The program might invoke business processing as it parses. The program can use
either DOM or SAX methods.
򐂰 A DB2 program written in any programming language might read the file and the following
functions may occur:
– Store the XML within a database without parsing
– Shred the document into one or more database tables
– Parse the document and perform any combination of storing, shredding and
processing.
– Query the XML and join it to relational tables
– Generate new XML output from query results
򐂰 DB2 can reference XML within DB2 commands and utilities.
򐂰 An application program written in C, C++, COBOL, PL/I or assembler, or a shell script
reads and parses the document file, processing the data as it parses.

It is also possible to use empty files to trigger the submission of a batch job. In this scenario,
the XML input exist elsewhere (such as within a database or messaging queue).

Exchanging files between programming languages, hardware and software platforms and
external systems always carries some risk of incorrect character translations. This can
happen due to automatic character conversions such as an FTP non-binary transfer or
deliberate conversions such as when using DRDA®. See 11.4, “Exchanging XML documents
between heterogeneous systems” on page 158 for additional information.

Chapter 3. XML sources, targets, and design patterns 27


3.2.2 Scheduled batch jobs
Scheduled batch jobs use the same design patterns as triggered jobs. However, the input is
generally collected throughout the day and waiting in a set of GDG members, a set of
specifically named files, or a messaging queue.

3.2.3 Web services and DB2, IMS, CICS TS

CICS TS and Web services


CICS TS receives requests for Web services using HTTP, SOAP, and REST protocols.
SOAP/XML conversion is performed to convert SOAP/XML-based requests into conventional
CICS commareas, which are passed to CICS applications using EXEC CICS LINK protocol.
See Figure 3-1.

CICS TS
V3R1

CICS Web
Services

Service SOAP/XML COMMAREA CICS


<XML SOAP
conversion or CONTAINER application program
requester message>

WSDL

COBOL, PLI,
C, C++ commarea Web Services WSBind
definition Assistant file

Figure 3-1 CICS TS and XML/SOAP

After the CICS application has completed, the updated commarea is converted from
commarea format into SOAP/XML and returned to the requester. Newer releases of CICS
allow channels and containers to replace commareas. Channels and containers address the
32 KB size restriction of commareas.

28 XML Processing Options on z/OS


CICS transform statement
Since CICS TS 4.1 you are able to generate or parse XML regardless of the communications
channels, using the new EXEC CICS TRANSFORM statement. With this statement you have
the same conversion capabilities as in WebService, but it is not dependent on the use of the
SOAP protocol using HTTP or MQ. This makes it even simpler to use XML messages in
existing or new CICS applications. See Figure 3-2.

CICS TS
V4.1

CICS
Channel and
Containers application program

Data in program structure


EXEC CICS
XML String Transform
SOAP/XML
DatatoXML
conversion

XML String
EXEC CICS
Data in program structure Transform
XMLtoData

COBOL, PLI,
C, C++ commarea
definition
Web Services WSBind
Assistant file
XML Schema,
WSDL
definition

Figure 3-2 CICS transform statement

Chapter 3. XML sources, targets, and design patterns 29


IMS and Web Services
As Figure 3-3 shows, IMS offers a number of interfaces for invoking IMS transactions.
y
IMS Connect /
W
S
WAS IMS

IMS Connect Java Client D


Java
C omp one nt
C onn ector for
Ja va
IMS O
T IMS IMS
L EJB / Be an TCP/IP Connect M
A Appls. DB

MQ to W WAS JMS to MQ Queues


S
Java MQ MQ-IMS O
IMS
IMS Bridge D
Comp one nt MQ Bridge T IMS
EJB / Be an DB
L (XCF)
M
A Appls.

W
WebSphere IICF S Ja va
WAS We bSp here
WebSphere D RA
D C ompo ne nt
IIC F JDBC
IICF / IMS
L EJB / Bea n
Clie nt TCP/IP ODBA IMS
DB DB

IMS Distributed JDBC W


S Java
WAS IMS
WAS zOS O
D Com pon ent
D istribu te d
JDBC
+ JDBC D IMS IMS
L EJB / Be an RMI/ Dri ve r B
IIOP A DB DB

IMS SOAP Gateway – W


S IMS SOAP Gatewa y IMS O
IMS
Technology Preview D
TCP/IP
T
IMS
L Connect M
A Appls. DB

Figure 3-3 IMS Web Services connectivity solutions

When IMS receives requests for Web Services using the SOAP protocol, XML converters are
used to convert XML-based requests into program-friendly data areas which are passed to
IMS application programs through an internal queue. After the application has completed, the
updated data area is then converted to XML and returned to the requester. See Figure 3-4.

p1 Inbound
XML Converter

In
Q

XML Traditional
WebSphere Application IMS Driver COBOL
Server V4 or above Connector Program
P1

Out
Q

p1 Outbound
XML Converter

IMS 7.1 or above

Figure 3-4 IMS and Web Services

30 XML Processing Options on z/OS


When the converter programs are written to use z/OS XML System Services, the XML
parsing is eligible to be offloaded to a zAAP or zIIP. RD/z generates converter routines with
the option of using z/OS XML System Services.

DB2 and Web services


DB2 participates in Web services as a provider through the use of DB2 stored procedures.
Web applications invoke the stored procedure through EXEC SQL CALL, as shown in
Figure 3-5. The parameters passed to the stored procedure can be any combination of DB2
native data types, including XML.

Web Services
Requester SOAP Server ODBC
HTTP JDBC
DB2

Stored
Procedure

Figure 3-5 DB2 as a Web services provider

As a Web services consumer, SQL statements request a WEB service through DB2 user
defined functions (UDFs). The service is invoked by the UDF and the UDF is requested by
including it within an SQL statement. The parameters passed to the UDF can be any
combination of native DB2 data types, including XML. See Figure 3-6.

SELECT col_a, col_b,


XYZ(col_c,col_d,”func”,
SQL DB2
user_id)
From my_table
User Web Services
Defined HTTP Server
SOAP
Function
XYZ
Figure 3-6 DB2 as a Web services consumer

3.2.4 WebSphere Application Server


WebSphere Application Server was designed to run Java J2EE workloads efficiently. It is
tightly integrated with WebSphere ESB and WebSphere MQ Messaging. As Figure 3-7 on
page 32 shows, many Java workloads rely on XML. WebSphere Application Server
applications can access Web services applications residing within CICS and IMS using
XML-based SOAP request.

Chapter 3. XML sources, targets, and design patterns 31


SOAP
HTTP CICS TS
IIOP
or
ct
nne
Co
WebSphere IMS
tor
Application nec
Con
Server

WebSphere
Connector MQ
J2EE Java applications Messaging

ODB
C
JDB
C
DB2

Figure 3-7 WebSphere Application Server and SOAP

3.2.5 Enterprise Service Bus, MQ Message Broker, Process Server


These WebSphere products are adept at generating, transforming, and consuming XML
messages. XML messages might be generated from events such as receipt of a fax or
completion of a batch job. In fact, the variety of sources is limited primarily by our
imaginations.

Message enrichment (adding to the content) and transformation are common tasks and are
often performed upon the XML portion of these messages. These products not only generate
and consume XML internally, they also exchange messages with each other and other
products, as shown in Figure 3-8.

MQI Human JMS


BPEL
Application Tasks Application

Enterprise Service Bus


DataPower
WebSphere
WebSphere MQ
Service
integration ESB
bus WebSphere
Message
Broker

WBI Web MQTT


CICS
Adapter Service SCADA

Figure 3-8 Enterprise Service Bus

32 XML Processing Options on z/OS


Key for abbreviations in Figure 3-8 on page 32:
MQTT MQ Telemetry Transport
WBI WebSphere Business Integration
MQI Message Queue Interface
JMS Java Messaging System
BPEL Business Processing Execution Language
SCADA Supervisory Control And Data Acquisition

3.2.6 DB2 as an XML warehouse and middle tier


With the implementation of pureXML in DB2 version 9, DB2 can be used as a traditional
relational database as well as a full-fledged XML database. This enables processing and
management of XML data, including importing, exporting, validation, transformation,
querying, and updating XML documents. It also allows merging of the two types of data. With
pureXML, SQL queries can include XML queries and XML queries can include SQL queries.

Some applications require an XML warehouse. The XML data will be stored and retrieved, but
there is no requirement to parse or validate the data. Other applications might require parsing
and processing of the data in addition to storing and retrieving the original XML string.

In scenarios where the original XML string is to be retrieved, storing it as XML ensures that
the original text can be returned. If the XML were converted into relational tables, it might be
possible to regenerate the original XML documents or data.

DB2 9 for z/OS provides new XML data types that allow XML to be stored as XML. The stored
XML can also be parsed and processed as needed. Applications that must access the XML
as XML frequently can benefit from storing the data in XML form.

For applications that must frequently access the data as XML and frequently access the data
as relational tables, it might be worthwhile to store the data in both its original XML form and a
relational form. See Figure 3-9.

XML XML column


DB2

Original
XML

XML shred

DB2 Relational
Data
XML query

Figure 3-9 DB2 as an XML warehouse

Chapter 3. XML sources, targets, and design patterns 33


3.2.7 IMS as an XML warehouse and middle tier
IMS V9 provides the means to:
򐂰 Retrieve and store XML data as XML
򐂰 Retrieve and store IMS records as XML documents with no changes to existing IMS
databases
򐂰 Convert the XML into IMS data structures and segments
򐂰 Convert from IMS data into XML
򐂰 View and map native hierarchal data to XML document
򐂰 Align IMS database (DBD) with XML schema

In scenarios where the original XML string is to be retrieved, storing the XML as XML ensures
that the original XML can be returned. If the XML is converted into IMS structures, it might be
possible to regenerate the original XML document, as illustrated in Figure 3-10.

XM L S chem a
IM S D B D
book

@ year seq P C B : B IB 2 1
BOOK
xs:d ate YEAR T IT L E P U B L IS H P R IC E
XM L title ch oice p u b lish er p rice
IM S
D ocum en ts xs:strin g xs:strin g xs:d ecim al
0:o o 0:o o
D a ta
AUT H E D IT
LAST F IR S T LAST F IR S T AFFL

au th o r au th o r

seq seq

last first last first affiliatio n

xs:strin g xs:strin g xs:strin g xs:strin g xs:strin g

Figure 3-10 IMS as a middle tier or warehouse

IMS/Java applications can also parse and process the XML data as needed, as shown in
Figure 3-11.

IMS DB Metadata
Business Logic XML Shredder,
XML Materializer
Code
IMS Dep. Region
Transaction and DLI
Message IMS Java
Processing App
Database Customer Code
View

A JDBC/SQL XML-DB
p
p
DB IMS Java Class Library
Mapping Base
to DL/I
APIs JNI

CEETDLI Interface Assembler Layer Interface to IMS

JDBC, JCA
Java to C
interface
interface

Figure 3-11 IMS as a Java/XML application server

34 XML Processing Options on z/OS


3.2.8 Messaging interfaces
A common design pattern for JMS and WebSphere MQ Messaging is to use a triggered
message queue. Each time the number of unread messages changes from zero to more than
zero, a message reading application for the queue is started. These started applications are
commonly called MQ listeners. On System z a queue trigger can start a CICS transaction or
submit a batch job. The CICS transaction or batch job then executes a program that reads
each queue message, parses, and processes the XML content of the message, applying
database updates and building and sending additional messages and MQ responses as
required.

WebSphere MQ Messaging on System z includes an easy means of triggering CICS


transactions and batch jobs. However, you can write your own trigger monitor program and
initiate the MQ queue reading programs in almost any way you need. Trigger monitor
programs typically run 24/7. Consequently, they are often started tasks.

DB2 V8 for System z provides an MQ reading and processing facility called MQListener.
MQListener monitors designated MQ queues and executes a listener program when
messages are present. The listener program then reads a queue message, calls a
user-provided DB2 stored procedure providing the message content as a parameter, then
commits. Each message is an independent unit of work. See Figure 3-12.

DB2 stored procedures can be written in assembler, COBOL, PL/I, REXX, C, C++ and SQL
Procedure Language. MQListener provides the MQ reading mechanism while the user
provided stored procedures provide the XML parsing and business processing. These stored
procedures might be reusable within your Web service and other business applications.

When large volumes of messages are possible, reading and processing multiple messages
simultaneously might be required. MQListener supports multi-threading and can initiate more
than one listener thread per queue.

For more information regarding MQListener, see DB2 Version 9.1 for z/OS Application
Programming and SQL Guide, SC18-9841.

WebSphere Get Listener


MQ Put
MQ message app
Client app message
Messaging

pp
message

rA
Trigger

ene
t
Lis
te
itia
In
Trigger
Monitor

Figure 3-12 MQ messaging triggered listener applications

Chapter 3. XML sources, targets, and design patterns 35


36 XML Processing Options on z/OS
4

Chapter 4. Overview of XML generation


Many applications must generate an XML string. This chapter gives a brief overview of the
options available on z/OS to achieve this.

© Copyright IBM Corp. 2009. All rights reserved. 37


4.1 Enterprise COBOL for z/OS
Enterprise COBOL for z/OS V3R3 added the XML GENERATE statement as an IBM
extension to the COBOL language. XML GENERATE accepts virtually any COBOL data
description and generates well-formed XML strings or documents.

See 5.1, “Generating XML from COBOL” on page 42 for details regarding the syntax, options,
and results of XML GENERATE.

4.2 Enterprise PL/I for z/OS


Enterprise PL/I for z/OS V3R3 introduced the built-in XMLCHAR function. XMLCHAR makes
generation of well-formed XML strings from PL/I data elements simple and reliable. See 5.2,
“Generating XML from PL/I” on page 48 for details regarding the syntax, options, and results
of XMLCHAR.

4.3 4.3 CICS TS


A new statement, EXEC CICS TRANSFORM DATATOXML, enables you to generate an XML
string from a program structure in COBOL, PL/I, or C. This functionality is added with CICS
TS 4.1. See 5.4, “Generating XML from CICS Web Services” on page 57 for details on
options, syntax, validation, and generation of converter modules.

4.4 Web Services in CICS TS


CICS TS has support for SOAP version 1.1 and 1.2. The Web services support enables your
CICS programs to be Web service requesters or providers. When acting as a requester, CICS
Web Services support generates the outbound XML string from data delivered in traditional
language structures such as comm areas or using channels and containers. See Figure 4-1.

C IC S T S

C IC S C IC S W e b
t r a n s a c tio n S e r v ic e s

B u s in e s s
a p p lic a t io n
CO M M AREA or S e r v ic e
S O A P M essage P r o v id e r
C o n t a in e r

Figure 4-1 CICS as a service requester

A batch utility helps you generate the necessary XML generator modules and commareas,
either from a XML schema definition or from a existing comm-area.

38 XML Processing Options on z/OS


CICS Web Services supports the following request types:
򐂰 Request only, no replies expected
򐂰 Request reply
򐂰 Request with optional reply

CICS Web Services supports HTTP/HTTPS and MQ as the transport mechanism.

Note: In the recently released version of CICS TS 4.1, there is a new feature, CICS XML
Assistants (DFHLS2SC and DFHSC2LS), that allows a CICS application to do XML
processing (generation and parsing) separate from any Web services connotations.

4.5 XML Toolkit for z/OS


The XML Toolkit Parser, C++ Edition provides parser classes for C++ programs. C++
programs can also use native C++ and other classes to generate XML.

The XML Toolkit XSLT Processor, C++ Edition is designed to transform XML to XML, XML to
HTML, and XML to text.

4.6 DB2 for z/OS


DB2 9 for z/OS provides thirteen functions for generating simple to complex XML strings and
documents. Document content can be derived from any combination of relational tables or
stored XML documents. These functions are described in 5.6, “DB2 for z/OS” on page 60.

Chapter 4. Overview of XML generation 39


40 XML Processing Options on z/OS
5

Chapter 5. How to generate XML


In this chapter we discuss generating well-formed XML strings from various languages and
the XML Toolkit for z/OS.

Tip: A binary zeros (null) character is not part of well-formed XML. Do not introduce binary
zeros or any other illegal character in XML or by not initializing FILLER, or by setting the
parameter length or null indicator incorrectly for a DB2 stored procedure parameter
containing XML.

© Copyright IBM Corp. 2009. All rights reserved. 41


5.1 Generating XML from COBOL
COBOL V3R3 introduced the XML GENERATE statement as an IBM extension to the
COBOL language. XML GENERATE will transform virtually any COBOL data description into
a well-formed XML string.

There are several options for generating XML strings. Each of the examples in this section
uses the COBOL data description shown in Example 5-1 and accompanying initialization
procedure as the source for XML string generation.

Example 5-1 COBOL XML GENERATE examples data description


01 personnel-redbooks-list.
05 personnel occurs 2 times.
10 name.
15 lastn pic x(32).
15 firstn pic x(32).
10 a2.
15 country pic xx.
15 redbooks pic s9(4) comp-5.

* Initializing Procedure
MOVE 'lastnName1' to lastn (1)
MOVE 'firstnName1' to firstn (1)
MOVE 'DE' to country (1)
MOVE 32767 to redbooks (1).
MOVE 'lastnName2' to lastn (2)
MOVE 'firstnName<' to firstn (2)
MOVE 'DK' to country (2)
MOVE 1 to redbooks (2).

5.1.1 COBOL XML GENERATE examples

basic element-style
The simplest use of XML GENERATE generates an XML string, but not a complete
document. Example 5-2 illustrates the required COBOL syntax and the resulting XML string.

Example 5-2 COBOL XML GENERATE basic element-style


XML GENERATE generated-xml-text FROM personnel-redbooks-list
COUNT IN generated-length
END-XML

Produces:
<personnel-redbooks-list>
<personnel>
<name>
<lastn>lastnName1</lastn>
<firstn>firstnName1</firstn>
</name>
<a2>
<country>DE</country>
<redbooks>32767</redbooks>
</a2>

42 XML Processing Options on z/OS


</personnel>
<personnel>
<name>
<lastn>lastnName2</lastn>
<firstn>firstnName&lt;</firstn>
</name>
<a2>
<country>DK</country>
<redbooks>1</redbooks>
</a2>
</personnel>
</personnel-redbooks-list>

By default, the generated XML string does not contain a standard XML document header. The
optional COUNT IN clause returns the number of generated character encoding units:
number of bytes for UTF-8 and single byte character sets or number of double-bytes for
UTF-16.

The generated XML element names are identical to the COBOL data element names.
COBOL data names often contain hyphens, and while use of hyphens is accepted within
XML, common XML convention uses underscores in place of hyphens. In Enterprise COBOL
V4R2 and later, users can use underscores in data names. For older programs, a simple
conversion of hyphen to underscore in element-names-only is shown in 5.1.4, “Hyphens in
element names” on page 46.

Note that the XML string is generated as a single contiguous string with no whitespace. The
generated string is presented here as it is displayed by an XML editor.

Element-style with XML declaration


The WITH DECLARATION clause adds a standard XML header to the beginning of the
generated string, as shown in Example 5-3.

Example 5-3 COBOL XML GENERATE with XML declaration


XML GENERATE generated-xml-text FROM personnel-redbooks-list
WITH DECLARATION
COUNT IN generated-length
END-XML

Produces:
<?xml version="1.0" encoding="IBM-037" ?>
<personnel-redbooks-list>
<personnel>
<name>
<lastn>lastnName1</lastn>
<firstn>firstnName1</firstn>
</name>
<a2>
<country>DE</country>
<redbooks>32767</redbooks>
</a2>
</personnel>
<personnel>
<name>
<lastn>lastnName2</lastn>

Chapter 5. How to generate XML 43


<firstn>firstnName&lt;</firstn>
</name>
<a2>
<country>DK</country>
<redbooks>1</redbooks>
</a2>
</personnel>
</personnel-redbooks-list>

attribute-style
The WITH ATTRIBUTES clauses causes XML GENERATE to produce an attribute-style XML
string rather than the default element-style string. See Example 5-4.

Example 5-4 COBOL XML GENERATE Attribute-Style


XML GENERATE generated-xml-text FROM personnel-redbooks-list
WIH ATTRIBUTES
COUNT IN generated-length
END-XML

Produces:
<personnel-redbooks-list>
<personnel>
<name lastn="lastnName1" firstn="firstnName1" />
<a2 country="DE" redbooks="32767" />
</personnel>
<personnel>
<name lastn="lastnName2" firstn="firstnName&lt;" />
<a2 country="DK" redbooks="1" />
</personnel>
</personnel-redbooks-list>

Attribute values are always designated with an equals symbol (=) and enclosed within
quotation marks. Because attributes have no end-tags, attribute-style requires fewer
characters. This reduction in space is sometimes attractive for large documents.

attribute-style with namespace


The NAMESPACE clause assigns a namespace to the outermost element and all its
subordinate elements and attributes, as shown in Example 5-5. NAMESPACE can only be
assigned when in a single XML GENERATE statement. The NAMESPACE-PREFIX clause is
optional and only allowed in conjunction with the NAMESPACE clause. NAMESPACE without
NAMESPACE-PREFIX will cause the generated string to qualify each element name with the
entire NAMESPACE name. NAMESPACE with NAMESPACE-PREFIX will cause the
generated string to qualify each element name with the provided namespace prefix.

Example 5-5 COBOL XML GENERATE with namespace


XML GENERATE generated-xml-text FROM personnel-redbooks-list
WIH ATTRIBUTES
NAMESPACE ‘http://example’ NAMESPACE-PREFIX ‘prl’
COUNT IN generated-length
END-XML

Produces:

44 XML Processing Options on z/OS


<prl:personnel-redbooks-list xmlns:prl="http://example">
<prl:personnel>
<prl:name lastn="lastnName1" firstn="firstnName1" />
<prl:a2 country="DE" redbooks="32767" />
/prl:personnel>
<prl:personnel>
<prl:name lastn="lastnName2" firstn="firstnName&lt;" />
<prl:a2 country="DK" redbooks="1" />
</prl:personnel>
</prl:personnel-redbooks-list>

5.1.2 XML GENERATE error handling


A number of errors are possible from XML GENERATE. XML GENERATE updates the
XML-CODE special register. It will contain zero when there are no errors and non-zero when
there are one or more errors.

Illegal characters for XML


When element and attribute values contain illegal characters, Enterprise COBOL for z/OS
returns 417 within the XML-CODE special register and automatically converts elements and
attributes containing illegal characters into a hexadecimal format. Many non-displayable
characters have no corresponding character within the ISO-10646 character set referenced
by the XML 1.0 standard. Continuing the previous examples, if the COBOL data element
lastn of name of personnel-redbooks-list contained a x’01’ followed by spaces, the
generated XML string would be changed to as follows:
<hex.lastn>014040404040404040404040404040404040404004040404040404040404040</hex.la
stn>.

This automatic conversion is not part of the XML standard, but it is extremely useful for finding
and removing program defects. Where unintentional inclusion of illegal characters is likely,
programs should check for XML-CODE 417 and execute the appropriate recovery.
Alternatively, programs can validate fields in advance of the XML GENERATE. As we show in
Example 5-6, you can define a set of allowable characters to use within a COBOL class test
to identify problem characters.

Example 5-6 COBOL test of illegal characters


Configuration Section.
Special-names.
*The following character class should be used to validate whether character
*fields contain only English language EBCDIC characters supported within XML.
CLASS ebcdic-english-and-xml IS
SPACE ‘.’ ‘<‘ ‘(‘ ‘+’ ‘|’ ‘&’
‘!’ ‘$’ ‘*’ ‘)’ ‘;’ ‘-’ ‘/’
‘,’ ‘%’ ‘_’ ‘>’ ‘?’ ‘‘’ ‘:’ ‘#’ ‘@’ “‘” ‘=’ ‘”’
‘a’ thru ‘i’ ‘j’ thru ‘r’ ‘~’ ‘s’ thru ‘z’
‘^’ ‘[‘ ‘]’ ‘{‘ ‘A’ thru ‘I’ ‘}’ ‘J’ thru ‘R’
‘\’ ‘S’ thru ‘Z’ ‘0’ thru ‘9’
x’05’ x’0D’ x’15’ x’25’.

IF field NOT ebcdic-english-and-xml


error routine
END-IF

Chapter 5. How to generate XML 45


There are a number of non-English language characters which are valid within the ISO-10646
character set that are not represented in the previous example. If you are creating XML
streams which include foreign language characters, À, Â, and Ç, for example, you could add
them to the class definition.

5.1.3 COBOL reserved words as element and attribute names


COBOL does not allow COBOL-reserved words as data item names. Therefore, XML element
and attribute names such as “first,” “last,” and “program-id” are difficult to create. COBOL
INSPECT ... REPLACING can be used to replace tag names of equal length.

5.1.4 Hyphens in element names


The routine in Example 5-7 is copied from Enterprise COBOL for z/OS Programming Guide
V4R1, SC23-8529. This routine will convert hyphens to underscores within element names,
but not element values, attribute names, or attribute values. Another option with Enterprise
COBOL V4R2 is to use underscores in the COBOL data names.

Example 5-7 COBOL hyphen in tag names to underscore routine


01 xmldoc pic x(16384).
01 charcnt comp-5 pic 9(5).
01 pos comp-5 pic 9(5).
01 tagstate comp-5 pic 9 value zero.
01 quotestate comp-5 pic 9 value zero

dash-o-underscore.
perform varying pos from 1 by 1 until pos > charcnt
if xmldoc (pos:1) = ‘<‘
move 1 to tagstate
end-if
if tagstate = 1
if xmldoc (pos:1) = ‘”’
move 1 to quotestate
else
move 0 to quotestate
end-if
end-if
if tagstate = 1 and quotestate = 0 and xmldoc (pos:1) = ‘-’
move ‘_’ to xmldoc (pos:1)
else
if xmldoc (pos:1) = ‘>’
move 0 to tagstate
end-if
end-if
end-perform.

5.1.5 Upper-case element names


COBOL is case-insensitive. The names ABC, Abc and abc are considered identical.
Traditional COBOL programs use upper case only for most names (program names,
paragraph names, data item names, and so forth). However, in recent years mixed case
names have been growing in popularity.

46 XML Processing Options on z/OS


XML is case sensitive, therefore elements named ABC, Abc, and abc are all distinct elements.
It is important within COBOL XML-generating programs to use names consistently, including
using a consistent case.

XML GENERATE generates element names that are identical to their source field names. To
produce lower-case element names, use lower-case COBOL data item names.

Alternatively, you can use a procedure similar to Example 5-7 on page 46 to shift upper-case
to lower case by replacing
if tagstate = 1 and quotestate = 0 and xmldoc (pos:1) = ‘-’
move ‘_’ to xmldoc (pos:1)

with
if tagstate = 1 and quotestate = 0
move function lower-case (xmldoc (pos:1)) to xmldoc (pos:1)

As with Example 5-7 on page 46, only element names are affected. Attribute names, attribute
values and element values will not be changed.

5.1.6 COBOL data attributes that suppress XML string generation


Some data elements are not eligible for inclusion within the generated XML string. Here is the
current list as of Enterprise COBOL for z/OS V4R2.
򐂰 Data types containing addresses have no value outside of the generating program.
Therefore, COBOL pointer data types (USAGE POINTER, PROGRAM-POINTER,
FUNCTION-POINTER, and OBJECT REFERENCE) are ignored during string generation.
򐂰 Data elements defined as filler, either implied or explicitly, are ignored during string
generation.
򐂰 SYNCHRONIZE alignment bytes (also known as slack bytes) are typically not referenced
or populated by COBOL programs and are also ignored during string generation.
򐂰 Data items containing the REDEFINES clause are ignored during string generation.
However, the data item being redefined is not ignored unless it also contains a
REDEFINES clause.

5.1.7 Multi-byte character encoding


The generated string will be created with the program’s default code-page except in the
following circumstances:
򐂰 The receiving data item is a national item (PIC N, USAGE NATIONAL or GROUP USAGE
NATIONAL). In this scenario, the generated string will be created in UTF-16BE (CCSID
1200).
򐂰 The ENCODING clause is used to specify a different codepage.

If one or more input data items is defined with PIC N, USAGE NATIONAL or GROUP USAGE
NATIONAL, then the output data item must be a national item.

When provided, the ENCODING clause must specify a codepage from the supported list of
code pages. See the appropriate revision of the Enterprise COBOL for z/OS Programming
Guide for the list which applies to your currently installed release.

Chapter 5. How to generate XML 47


5.2 Generating XML from PL/I
PL/I provides the XMLCHAR function that was added to the language with V3R3 of
Enterprise PL/I. XMCHAR generates the well-formed XML strings from a PL/I data structure.
XMLCHAR passes the XML string back to the application in a buffer. The application can then
combine multiple fragments into a complete XML document on an external storage device.

We created a simple PL/I program to show the usage of XMLCHAR with which we build a
simple XML string. The complete example is given in B.1, “PL/I example to generate XML” on
page 165.

The output of this example is given in Example 5-8. It has been edited from the 131 character
wide listing into a more readable form here.

Example 5-8 Output from a PL/I program using XMLCHAR


<Personnel><Name><first>Hans-Dieter</first><last>Mertiens</last>
</Name><a2><country>DE</country><redbooks>10</redbooks></a2>
</Personnel>
<Personnel><Name><first>Mogens</first><last>Conrad</last>
</Name><a2><country>DK</country><redbooks>2</redbooks></a2>
</Personnel>

Through Enterprise PL/I 3.6 nothing was done towards conversion into another codepage, for
example, UTF-8. With Version 3.7 of Enterprise PL/I a new built-in function MEMCONVERT
was provided. It converts the data in a source buffer from the specified source codepage to a
specified target codepage, stores the result in a target buffer, and returns an unscaled REAL
FIXED BINARY value specifying the number of bytes written to the target buffer.
MEMCONVERT is based on CUNLCNV, which comes with z/OS support for Unicode. It might
be helpful to look at z/OS Support for Unicode: Using Unicode Services, SA22-7649.

We added a small piece of code according to the description above. The result of the
conversion is shown in Example 5-9. The first part (1) of the hexadecimal printout shows the
input to MEMCONVERT, which is encoded in 037. The second part (2) shows the same string
encoded in UTF-8. For better reading we have added the clear text to the first row of the 037
encoded text.

Example 5-9 Output from the MEMCONVERT built-in function


-------- source 037 1
< P e r s o n n e l > < N a m e > < f i r s t > M o g e n s < /
4CD78599 A2969595 85936E4C D5819485 6E4C8689 99A2A36E D4968785 95A24C61
868999A2 A36E4C93 81A2A36E C3969599 81844C61 9381A2A3 6E4C61D5 8194856E
4C81F26E 4C8396A4 95A399A8 6EC4D24C 618396A4 95A399A8 6E4C9985 84829696
92A26EF2 4C619985 84829696 92A26E4C 6181F26E 4C61D785 99A29695 9585936E
-------- target 1208 / UTF-8 2
3C506572 736F6E6E 656C3E3C 4E616D65 3E3C6669 7273743E 4D6F6765 6E733C2F
66697273 743E3C6C 6173743E 436F6E72 61643C2F 6C617374 3E3C2F4E 616D653E
3C61323E 3C636F75 6E747279 3E444B3C 2F636F75 6E747279 3E3C7265 64626F6F
6B733E32 3C2F7265 64626F6F 6B733E3C 2F61323E 3C2F5065 72736F6E 6E656C3E

With XMLCHAR, and MEMCONVERT you should be able to handle XML generation in a way
that the final XML document can also be sent to other platforms such as UNIX or Windows®.

48 XML Processing Options on z/OS


5.3 XML Toolkit for z/OS
The toolkit includes XSLT processing capabilities through the XSLT Processor, C++ Edition,
which is a port of the IBM XSLT4C XSLT Processor. This enables you to perform XML
transformation in both the UNIX and the MVS environment on z/OS.

See the XML Toolkit for z/OS user’s guide for detailed information about how to set up your
environment to enable XSLT transformation processing on z/OS:
http://www-03.ibm.com/servers/resources/ixmza290.pdf

With the toolkit you receive programming samples to exploit the SAX, DOM, and XALAN API
for XSLT processing. The samples are shipped in non-XPLINK version, but you are able to
build your own versions and bind with XPLINK for better performance.

In Example 5-10, we have used the XALAN API to transform a XML document to a HTML
page. It shows the XML document used as input to the transformation.

Example 5-10 XML document before transformation


<?xml version="1.0" encoding="ibm-1047-s390" ?>
<library>
<book language="English">
<author country="UK">Lewis Carrol</author>
<title>Alice's Adventures in Wonderland</title>
<year>1865</year>
<ISBN>0000123456</ISBN>
</book>
<book language="Danish">
<author country="DK">Flemming Quist Moeller</author>
<title>Cykelmyggen Egon</title>
<year>1967</year>
<ISBN>0000123457</ISBN>
</book>
<book language="English">
<author country="US">Mike Ebbers</author>
<author country="DE">Hans-Dieter Mertiens</author>
<author country="US">Michael Todd</author>
<author country="IN">Nagesh Subrahmanyam</author>
<author country="DK">Mogens Conrad</author>
<title>XML Processing on z/OS</title>
<year>2009</year>
<ISBN>0000123458</ISBN>
</book>
</library>

Chapter 5. How to generate XML 49


We next define the needed transformation in a XSL stylesheet. Example 5-11 shows the XSL
document needed to transform the XML input document to a HTML document.

Example 5-11 XSLT used to transform XML to HTML page


<?xml version="1.0" encoding="ibm-1047" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:template match="/">
<html>
<head>
<title>Library</title>
<h2>My very small library</h2>
</head>
<body bgcolor="#ffffff">
<table border="3">
<tr>
<td>ISBN</td>
<td>Title</td>
<td>Author</td>
<td>Year</td>
</tr>
<xsl:for-each select="library/book">
<tr>
<td><xsl:apply-templates select="ISBN"/></td>
<td><xsl:apply-templates select="title"/></td>
<td>
<xsl:for-each select="author">
<xsl:value-of select="."/>
<br></br>
</xsl:for-each>
</td>
<td><xsl:apply-templates select="year"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>

</xsl:stylesheet>

First we used the XALAN command line interface to perform the transformation.
Example 5-12 shows the command line used.

Example 5-12 Xalan command line


Xalan -i 2 -e ibm-1047-s390 -o library.htm library.xml library.xsl

50 XML Processing Options on z/OS


Parameters used in Example 5-12 on page 50 are as follows:
򐂰 -i
Indention added on output document, for easy reading, default is no indention.
򐂰 -e
Encoding on output document, default is UTF-16.
򐂰 -o
Output file, XML input file and XSL input file

After running the Xalan command the resulting file library.htm will contain the html code
seen in Example 5-13.

Example 5-13 HTML output from Xalan command


<?xml version="1.0" encoding="ibm-1047-s390"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Library</title>
<h2>My very small library</h2>
</head>
<body bgcolor="#ffffff">
<table border="3">
<tr>
<td>ISBN</td>
<td>Title</td>
<td>Author</td>
<td>Year</td>
</tr>
<tr>
<td>0000123456</td>
<td>Alice's Adventures in Wonderland</td>
<td>Lewis Carrol<br/>
</td>
<td>1865</td>
</tr>
<tr>
<td>0000123457</td>
<td>Cykelmyggen Egon</td>
<td>Flemming Quist Moeller<br/>
</td>
<td>1967</td>
</tr>
<tr>
<td>0000123458</td>
<td>XML Processing on z/OS</td>
<td>Mike Ebbers<br/>Hans-Dieter Mertiens<br/>Michael Todd<br/>Nagesh
Subrahmanyam<br/>Mogens Conrad<br/>
</td>
<td>2009</td>
</tr>
</table>
</body>
</html>

Chapter 5. How to generate XML 51


The XML document is now transformed to a HTML document that presents the information
suitable for reading. See Figure 5-1.

Figure 5-1 HTML result from XSLT transformation

The Xalan command line interface is the simplest way to activate the Toolkit and transform a
XML document. On z/OS you have two other alternatives: Call the XSLT APIs from C or C++
program from the UNIX environment or from the MVS environment. The Toolkit provides a
number of sample programs to be used as a starter and you might enhance these examples
with you own code.

In Example 5-14, we have moved the source code for sample program SimpleTransform to a
MVS data set and compiled and linked it on MVS. To apply to MVS naming rules,
SimpleTransform is renamed SMPLTRNS and Xalan memory manager module used in the
program is renamed XALANMMI.

Example 5-14 JCL to compile SMPLTRNS


//COMPILE JOB MSGLEVEL=(1,1),REGION=0M
//JOBLIB DD DSNAME=CEE.SCEERUN,DISP=SHR
// DD DSNAME=CEE.SCEERUN2,DISP=SHR
// DD DSNAME=CBC.SCCNCMP,DISP=SHR
//STEP1 EXEC PGM=CCNDRVR,PARM='/CXX OPTFILE(DD:OPTS),OBJ,LIST'
//OPTS DD *
LANGLVL(EXTENDED)
NOSEARCH SEARCH(./,
/usr/lpp/ixm/IBM/xml4c-5_7/include/,
/usr/lpp/ixm/IBM/xslt4c-1_11/include/,
/usr/lpp/ixm/IBM/xslt4c-1_11/include/xalanc/Include/,
/usr/lpp/ixm/IBM/xslt4c-1_11/include/xalanc/XSLT,
//'CONRAD.BATCH.+',
//'CEE.SCEEH.+',
//'CBC.SCLBH.+')
DEFINE(OS390=1)
DEFINE(_OPEN_THREADS=1)
DEFINE(_XOPEN_SOURCE_EXTENDED=1)
/*
//SYSLIN DD DSNAME=CONRAD.BATCH.OBJ(SMPLTRNS),DISP=SHR
//SYSPRINT DD SYSOUT=A
//SYSIN DD DSNAME=CONRAD.BATCH.CPP(SMPLTRNS),DISP=SHR
//SYSUT1 DD DUMMY
/*

52 XML Processing Options on z/OS


After the compile job is executed, SMPLTRNS is link-edited using the JCL in Example 5-15.

Example 5-15 JCL to link-edit the program


//LINKEDIT JOB MSGLEVEL=(1,1),REGION=0M
//BIND1 EXEC PGM=IEWL,PARM='OPTIONS=OPTS'
//OPTS DD *
AMODE=31,RMODE=ANY
DYNAM=DLL,ALIASES=NO,UPCASE=NO,
LIST=SUMMARY,MAP=NO,XREF=NO,
REUS=RENT,EDIT=YES,AC=0,CALL=YES,CASE=MIXED
/*
//SYSLIB DD DISP=SHR,DSN=CEE.SCEELKEX
// DD DISP=SHR,DSN=CEE.SCEELKED
// DD DISP=SHR,DSN=CEE.SCEECPP
// DD DISP=SHR,DSN=CEE.SCEELIB
// DD DISP=SHR,DSN=CBC.SCLBSID
//SYSLIB1 DD DISP=SHR,DSN=IXM.SIXMEXP
//SYSLIB2 DD DISP=SHR,DSN=CONRAD.BATCH.OBJ
//SYSLMOD DD DISP=SHR,DSN=CONRAD.BATCH.LOAD
//SYSDEFSD DD DUMMY
//SYSPRINT DD SYSOUT=*
//SYSLIN DD *
INCLUDE SYSLIB(IOSTREAM)
INCLUDE SYSLIB(COMPLEX)
INCLUDE SYSLIB(C128N)
INCLUDE SYSLIB1(IXM4C57X)
INCLUDE SYSLIB1(IXMLC21X)
INCLUDE SYSLIB2(SMPLTRNS)
ENTRY CEESTART
NAME SMPLTRNS(R) RC=0
/*

For both the compile and the link-edit jobs, consult your systems programmer to get the
library names used on your system.

To run SimpleTransform on the MVS environment, we made a small source code change. The
original SimpleTransform assumes that the program is invoked with a current directory
pointing to the input files. When running as a batch job on z/OS, we do not have a current
directory and the program source is changed to include the entire path to the input files.
Example 5-16 shows the JCL.

Example 5-16 Same transformation using JCL


//SMPLTRNS JOB MSGLEVEL=(1,1),CLASS=A,REGION=0M
/*JOBPARM SYSAFF=SC80,L=999
//*
//STEP1 EXEC PGM=SMPLTRNS
//STEPLIB DD DSN=CONRAD.BATCH.LOAD,DISP=SHR
// DD DSN=IXM.SIXMLOD1,DISP=SHR
/*

Chapter 5. How to generate XML 53


Example 5-17 shows the source code for SimpleTransform. The changes to the original code
are marked.

Example 5-17 Changed source code for SimpleTransform


/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <xalanc/Include/PlatformDefinitions.hpp>

#if defined(XALAN_CLASSIC_IOSTREAMS)
#include <iostream.h>
#else
#include <iostream>
#endif

#include <xercesc/util/PlatformUtils.hpp>

#include <xalanc/XalanTransformer/XalanTransformer.hpp>
#include "XALANMMI.hpp"

/**
* Example of the ICU's customizable memory management which can
* be used conjunction with Xalan's pluggable memory management feature
*/
#if defined(XALAN_USE_ICU)
#include "unicode/uclean.h"

static XalanMemoryManagerImpl s_memoryManager;

void*
icu_malloc(const void * /* context */, size_t size)
{
return s_memoryManager.allocate(size);
}

void*
icu_realloc(const void * /* context */, void * mem, size_t size)
{
s_memoryManager.deallocate(mem);

54 XML Processing Options on z/OS


return s_memoryManager.allocate(size);
}

void icu_free(const void * /* context */, void * mem)


{
s_memoryManager.deallocate(mem);
}

#endif

int
main(
int argc,
char* /* argv */ݨ)
{
XALAN_USING_STD(cerr)
XALAN_USING_STD(endl)

int theResult = -1;

if (argc != 1)
{
cerr << "Usage: SimpleTransform"
<< endl
<< endl;
}
else
{
try
{
XALAN_USING_XERCES(XMLPlatformUtils)

XALAN_USING_XERCES(XMLUni)

XALAN_USING_XALAN(XalanTransformer)

XalanMemoryManagerImpl memoryManager;

#ifdef XALAN_USE_ICU
UErrorCode status = U_ZERO_ERROR;

u_setMemoryFunctions(0, icu_malloc, icu_realloc, icu_free, &status);

if(U_FAILURE(status))
{
cerr << "Initialization of ICU failed! "
<< endl
<< endl;

return -1;
}
#endif

// Call the static initializer for Xerces.


XMLPlatformUtils::Initialize(
XMLUni::fgXercescDefaultLocale,

Chapter 5. How to generate XML 55


0,
0,

&memoryManager );

// Initialize Xalan.

XalanTransformer::initialize( memoryManager );

{
// Create a XalanTransformer.
XalanTransformer theXalanTransformer( memoryManager );

// The assumption is that the executable will be run


// from same directory as the input files.

// When running under MVS these assumption is not fullfilled


// full path applied instead
// for more practical use you should get the file names from the PARM statement
// this is left as an exercise for the reader

theResult = theXalanTransformer.transform
("/u/conrad/SimpleTransform/library.xml",
"/u/conrad/SimpleTransform/library.xsl",
"/u/conrad/SimpleTransform/library.htm");

if(theResult != 0)
{
cerr << "SimpleTransform Error: \n" << theXalanTransformer.getLastError()
<< endl
<< endl;
}
}

// Terminate Xalan...
XalanTransformer::terminate();

// Terminate Xerces...
XMLPlatformUtils::Terminate();

// Clean up the ICU, if it's integrated...


XalanTransformer::ICUCleanUp();
}
catch(...)
{
cerr << "Initialization failed!" << endl;
}
}

return theResult;
}

56 XML Processing Options on z/OS


The sample program SMPLTRNS does not set the encoding and indention options we used in
the command line sample above. This results in a output file with UTF-16 as encoding and no
indentions for easy reading. Seen through a browser, the result is the same.

5.4 Generating XML from CICS Web Services


When CICS is a service requester, the business application program builds the data to be
transformed into XML and sends it to the service provider in the channel or container
structures built for the request. Figure 5-2 gives a overview of the process.

CICS TS

User transaction

Data mapping
Pipeline

Handler

Handler

Handler

SOAP REQUEST
Service
Provider
SOAP RESPONSE

Figure 5-2 CICS as Web services requester

The applications program passes data to the CICS Web Services Interface using the
command EXEC CICS INVOKE SERVICE. The request is passed through a pipeline and
sent to the target provider. The information in the wsbind file associated with this Web service
enables CICS to convert data delivered in the language structure into an XML document. The
pipeline handlers convert the XML document into a SOAP message. You are able to add extra
pipeline handlers for security, journaling, or other purposes

If the application expects to receive a reply from the provider, the response is returned
through the pipeline, converted from XML to the corresponding language structure, and
returned to the application program through the same channel as used for submitting the
request.

Chapter 5. How to generate XML 57


5.4.1 CICS Web Services Assistant
This utility provides a tool to generate the wsbind file that contains information to make the
transformation from language structure to XML or from XML to language structure.

The tool contains two programs:


򐂰 DFHLS2WS, that from a existing language structure constructs a WSDL document
򐂰 DFHWS2LS, that from a WSDL constructs a language structure

Both programs also create the WSBIND file.

Bottom up
CICS HFS
PDS
Web Services
Assistant WSBind
Language
Structure
Data mapping WSDL
DFHLS2WS

Top down
PDS

HFS CICS Language


Web Services Structure
WSDL Assistant
Schema
HFS
DFHWS2LS
WSBind

Figure 5-3 CICS Web Services Assistant

The Web Services Assistant supports COBOL, PL/I, C, and C++. Example 5-18 shows a
COBOL call.

Example 5-18 CICS Web Services Assistant, JCL Sample, DFHLS2WS


//MYLS2WS JOB ’accounting information’,name,MSGCLASS=A
// SET QT=’’’’
//JAVAPROG EXEC DFHLS2WS,
// TMPFILE=&QT.&SYSUID.&QT
//INPUT.SYSUT1 DD *
PDSLIB=//CICSHLQ.CICS.SDFHSAMP
REQMEM=DFH0XCP4
RESPMEM=DFH0XCP4
LANG=COBOL
PGMNAME=DFH0XCMN
URI=exampleApp/inquireSingle
PGMINT=CHANNEL
WSBIND=/u/exampleapp/wsbind/inquireSingle.wsbind
WSDL=/u/exampleapp/wsdl/inquireSingle.wsdl
/*

58 XML Processing Options on z/OS


CICS Web Services supports the following security protocols:
򐂰 SSL/TLS
򐂰 WS-Security
򐂰 WS-Trust
򐂰 Customized Security handler

For more information about CICS Web Services, see the following publications at the
following Web page:
http://www.redbooks.ibm.com
򐂰 Implementing CICS Web Services, SG24-7657
򐂰 Securing CICS Web Services, SG24-7658
򐂰 Developing Web Services Using CICS, WMQ and WMB, SG24-7425

5.5 CICS Transform statement


Beginning with CICS TS 4, you are independent of the communication channel when
generating XML. As a supplement to CICS WebService, the TRANSFORM statement (shown
in Example 5-19) allows you to generate XML in your application and receive the resulting
XML string back in the application program for further processing. In addition, you can store
or send the XML string through a channel other than HTTP or MQ without using the SOAP
protocol.

Example 5-19 Transform statement: Data to XML


EXEC CICS TRANSFORM DATATOXML
XMLTRANSFORM('MyXmlTransformName')
CHANNEL('MyChannelName')
DATCONTAINER('SourceContainerName')
XMLCONTAINER('TargetContainerName')

Conversion modules are available to prepare for the TRANSFORM statement with the same
tools as used for CICS Web Services. See 5.4.1, “CICS Web Services Assistant” on page 58.

Validation
The default for the TRANSFORM statement is that checking is performed to ensure the
message is well-formed. For testing purposes it is possible to add a control for valid XML. To
enable validation you must:
򐂰 Ensure that the XML binding and the schema are in the same location on z/OS UNIX. The
XMLTRANSFORM resource defines these files to CICS. You can use the INQUIRE
XMLTRANSFORM command to check the location of each file.
򐂰 Turn validation on for the application. Use the CEMT or SPI command SET
XMLTRANSFORM(name) VALIDATION, where name is the XMLTRANSFORM resource.

The result from the validation control is not returned to the application, but only
communicated through written messages. Check the system log to learn if the XML
transformation is valid:
򐂰 Message DFHML0508 indicates that the XML was successfully validated
򐂰 Message DFHML0507 indicates that the validation failed.

Chapter 5. How to generate XML 59


5.6 DB2 for z/OS
DB2 for z/OS V8 introduced the following XML generation functions:
򐂰 XML2CLOB (replaced with XMLSERIALIZE in Version 9)
򐂰 XMLAGG returns an ordered XML string of non-null values
򐂰 XMLCONCAT returns an XML string containing multiple XML strings
򐂰 XMLELEMENT returns a complete XML element string
򐂰 XMLFOREST returns an XML string consisting of 1 to many elements. Binary values can
be expressed in hex or BASE64
򐂰 XMLNAMESPACE returns a namespace declaration

DB2 9 for z/OS introduced these additional XML functions:


򐂰 XMLATTRIBUTE returns an XML string containing an attribute
򐂰 XMLCOMMENT returns an XML comment from a string expression
򐂰 XMLDOCUMENT returns a XML string consisting of a parent element
򐂰 XMLPI returns an XML string consisting of a single processing instruction
򐂰 XMLQUERY uses an XPath query to return an XML string from an XML string
򐂰 XMLSERIALIZE converts the output of these XML functions to CLOB, BLOB, or DBCLOB,
can also include an XML declaration
򐂰 XMLTEXT returns an XML value from a string expression

These functions can be combined to create well-formed XML strings or documents. We have
a series of examples, beginning with Example 5-20, and we show at the bottom of each what
the instructions produce.

Note: All of the results for these examples have been formatted with white space for ease
of interpretation. The DB2 functions actually return the XML string as one contiguous
stream with no white space.

Example 5-20 DB2 XMLELEMENT function


select xmlelement (name "dept", emplst.department)
from testdb.employees emplst
group by emplst.department

Produces:
<dept>2.</dept>

By default, all DB2 XML generating functions return an internal XML data type that cannot be
placed directly into a host variable. XMLSERIALIZE allows us to convert the internal XML
data type into a character data type. This character version can be returned to a program host
variable. XMLSERIALIZE also replaces special characters with the appropriate escape
sequences (for example, < into &lt;).

The XMLSERIALIZE call in Example 5-21 on page 61 produces equivalent results to


Example 5-20. However, it places the output into a program-native character set host variable
(probably EBCDIC on System z). Had we declared our host variable as a UTF-8 host variable,
DB2 would have provided the XML results to the program in UTF-8.

60 XML Processing Options on z/OS


Example 5-21 DB2 XMLSERIALIZE
exec sql select
xmlserialize ( xmlelement (name "dept", emplst.department)
as clob(1000)
)
into :xml-string
from testdb.employees emplst
group by emplst.department
end-exec.

Produces in the program’s native character set:


<dept>2.</dept>

Example 5-22 returns the generated XML string in UTF-8.

Example 5-22 DB2 XMLSERIALIZE returning to a UTF-8 host variable


01 xml-string PIC X(1000).
EXEC SQL DECLARE :xml-string VARIABLE CCSID 1208.

exec sql select


xmlserialize ( xmlelement (name "dept", emplst.department)
as clob(1000)
)
into :xml-string
from testdb.employees emplst
group by emplst.department
end-exec.

Produces:
<dept>2.</dept>

Arrays of elements or arrays of strings are returned with the XMLAGG function, as shown in
Example 5-23.

Example 5-23 DB2 XMLAGG array of element


exec sql select
xmlserialize ( xmlagg (
xmlelement (name "lname",emplst.last_name)
order by emplst.last_name
) as clob(1000)
) as "xmloutput"
into :xml-string
from testdb.employees emplst
end-exec.

Produces:
<lname>CONRAD</lname>
<lname>MERTIENS</lname>
<lname>SUBRAHMANYAM</lname>

Chapter 5. How to generate XML 61


Example 5-24 shows that XMLCONCAT is used to place one XML string at the end of
another.

Example 5-24 DB2 XMLCONCAT array of element list


exec sql select
xmlserialize ( xmlagg (xmlconcat (
xmlelement (name "lname",emplst.last_name),
xmlelement (name "fname",emplst.first_name)
) order by emplst.last_name
) as clob(1000)
) as "xmlout"
into :xml-string
from testdb.employees emplst
end-exec.

Produces:
<lname>CONRAD</lname><fname>MOGENS</fname>
<lname>MERTIENS</lname><fname>HANS-DIETER</fname>
<lname>SUBRAHMANYAM</lname><fname>NAGESH</fname>

A parent element is also created with XMLELEMENT. See Example 5-25.

Example 5-25 DB2 XMLELEMENT adding a parent element


exec sql select
xmlserialize ( xmlagg ( xmlelement (name "emp", xmlconcat(
xmlelement (name "lname",emplst.last_name),
xmlelement (name "fname",emplst.first_name)
)
) order by
emplst.last_name
) as clob(1000)
) as "xmlout"
into :xml-string
from testdb.employees emplst
end-exec.

Produces:
<emp>
<lname>CONRAD</lname><fname>MOGENS</fname>
</emp>
<emp>
<lname>MERTIENS</lname><fname>HANS-DIETER</fname>
</emp>
<emp>
<lname>SUBRAHMANYAM</lname><fname>NAGESH</fname>
</emp>

The XMLELEMENT (Example 5-26 on page 63) can return binary values in either base64 or
hex.

62 XML Processing Options on z/OS


Example 5-26 DB2 XMLELEMENT return binary column in base64
exec sql select
xmlserialize ( xmlagg ( xmlelement (name "emp", xmlconcat(
xmlelement (name "lname",emplst.last_name),
xmlelement (name "fname",emplst.first_name),
xmlelement (name "bioid",emplst.biometric_id
option xmlbinary base64
)
)
) order by
emplst.last_name
) as clob(1000)
) as "xmlout"
into :xml-string
from testdb.employees emplst
end-exec.

Produces:
<emp>
<lname>CONRAD</lname>
<fname>MOGENS</fname>
<bioid>8PLx8fHyQEA=</bioid>
</emp>
<emp>
<lname>MERTIENS</lname>
<fname>HANS-DIETER</fname>
<bioid>8PHx8fHxQEA=</bioid>
</emp>
<emp>
<lname>SUBRAHMANYAM</lname>
<fname>NAGESH</fname>
<bioid>9/Hw8PPyQEA=</bioid>
</emp>

The XMLATTRIBUTES function (shown in Example 5-27) can be used to return attribute-style
XML rather than element-style.

Example 5-27 DB2 XMLATTRIBUTES to generate attribute-style XML string


exec sql select
xmlserialize ( xmlagg ( xmlelement (name "emp",
xmlattributes ( emplst.last_name as lname,
emplst.first_name as fname
)
) order by
emplst.last_name
) as clob(1000)
) as "xmlout"
into :xml-string
from testdb.employees emplst
end-exec.
Produces:
<emp LNAME="CONRAD" FNAME="MOGENS"/>
<emp LNAME="MERTIENS" FNAME="HANS-DIETER"/>
<emp LNAME="SUBRAHMANYAM" FNAME="NAGESH"/>

Chapter 5. How to generate XML 63


The creation of a complete document requires adding an XML declaration and providing a
root element, as shown in Example 5-28.

Example 5-28 DB2 Complete document with declaration and root element
exec sql select
xmlserialize ( xmlelement (name "emp_list",
xmlagg ( xmlelement (name "emp",
xmlattributes ( emplst.last_name as lname,
emplst.first_name as fname
)
) order by
emplst.last_name
)
) as clob(1000)
including xmldeclaration
) as "xmlout"
into :xml-string
from testdb.employees emplst
end-exec.

Produces
<?xml version="1.0" encoding="UTF-8"?>
<emp_list>
<emp LNAME="CONRAD" FNAME="MOGENS"/>
<emp LNAME="MERTIENS" FNAME="HANS-DIETER"/>
<emp LNAME="SUBRAHMANYAM" FNAME="NAGESH"/>
</emp_list>

Notice that the preceding XML declaration specified encoding as UTF-8. DB2 assumes all
documents will be output in UTF-8. If you are outputting the document with some other
character encoding, you might want to generate your declaration as a simple text string and
concatenate it in your program to your generated XML string.

DB2 for z/OS includes three other XML functions that are not typically used to directly
generate XML:
򐂰 XMLCAST allows generated XML text to be converted into other host variable types; for
example, a numeric XML element can be cast into a COBOL numeric host variable
򐂰 XMLTABLE extracts data from an XML document and converts it into one or more rows of
data
򐂰 XMLPARSE parses input XML documents, with optional schema validation. The resulting
document can be stored as an XML column or shredded into conventional relational data

64 XML Processing Options on z/OS


6

Chapter 6. Overview of parsing


technologies on z/OS
This chapter provides a high level view of the various XML parsing technologies available in
z/OS.

© Copyright IBM Corp. 2009. All rights reserved. 65


6.1 z/OS XML System Services
z/OS XML System Services (z/OS XML) provides functionality to aid in parsing of XML
streams with or without validation. XML System Services provides both Assembler and
C/C++ language bindings to the user. The C services conform to the Language
Environment® so that they can be called directly from a COBOL or PL/I program. However
COBOL- and PL/I-specific language bindings are not provided or supported. These services
provide an alternative to the language-specific native parsers.

Note: The z/OS XML System Services parser does not have any Language Environment
dependencies. You can use the z/OS XML parser even in service request block (SRB)
mode.

z/OS XML System Services uses a buffer-in buffer-out technique. Input to and output from the
parser might span multiple buffers. This allows the application to handle large XML strings
that would not fit in its memory. Consequently, the XML parse does not provide a SAX or
DOM type interface.

Further, the application is responsible for managing the buffers. However, buffer management
is simplified because the input text stream can be broken at any point, even in the middle of a
multi-byte character. More information regarding buffer management can be found in 6.1.3,
“Buffer handling with XML System Services” on page 68.

The application is responsible for reading in the XML string, providing flexibility to the
application. The XML string can be read from a MVS data set, a file in the z/OS UNIX file
system, or VSAM cluster, to name a few possible sources.

z/OS XML System Services does not provide services for generating XML streams or
documents. XML generation must be accommodated through other services.

z/OS XML System Services are compatible with multi-threaded and multi-tasking
environments. The interfaces are written so that they communicate through a thread/task
level control block (parser instance memory area or PIMA). This provides the thread/task level
separation required for reliable multi-threading and multi-tasking.

66 XML Processing Options on z/OS


6.1.1 Parsed XML data stream
Figure 6-1 illustrates a returned XML parsed data stream.

GXLHXEC_TOK_BUFFER_INFO
record length
datastream options
parse status
buffer length used
offset to error record
GXLHXEC_TOK_START_ELEM
record length
GXLHXEC_TOK_START_ELEM
record length
GXLHXEC_TOK_CHAR_DATA
record length
GXLHXEC_TOK_START_ELEM
record length
GXLHXEC_TOK_CHAR_DATA
record length
GXLHXEC_TOK_ATTR_NAME
record length
GXLHXEC_TOK_ATTR_VALUE
record length
GXLHXEC_TOK_END_ELEM
record length
GXLHXEC_TOK_END_ELEM
record length
GXLHXEC_TOK_END_ELEM
record length

Figure 6-1 z/OS XML System Services parsed data stream

Notes for Figure 6-1:


򐂰 Each document produces a minimum of one buffer info record and one start element
record.
򐂰 Each record within the parsed data stream includes its length. The position of the next
record is calculated using the previous record’s position and length.

The parsed XML data stream contains unique record type identifiers for the different
components within an XML document. Among the record types are:
򐂰 XML declaration, when present
򐂰 Start of an element
򐂰 Character value for an element, when present
򐂰 End of an element
򐂰 Name of an attribute
򐂰 Value of an attribute
򐂰 Namespace declaration

These record types are similar to the SAX parsing callback events. Not coincidentally, the
records tend to appear in the same order SAX callback events occur. However, not every SAX
event is represented in the XML parsed data stream.

Applications can invoke z/OS XML System Services directly using a simple API. This
approach is useful within languages lacking direct XML parsing support, such as REXX and
assembler. It is also useful when z/OS XML System Services features are required but not
available within the host language’s built-in features. It can also facilitate non-traditional
parsing needs. For example, a complete SAX parsing implementation might be far more

Chapter 6. Overview of parsing technologies on z/OS 67


elaborate than is required for a simple application. Directly invoking the z/OS XML System
Services might be a simpler solution.

A key benefit of z/OS XML System Services is the ability to redirect portions of XML parsing
to zIIP or zAAP specialty engines, which can lower software costs. Most software products
using z/OS XML System Services run in task mode and will offload most of the XML
processing to a zAAP when available.

z/OS V1R10 added the ability to parse a document with validation. A document can be
validated against an XSD schema. For z/OS V1R9, the validation capability was added to the
parser with PTF UA44802.

6.1.2 Programming interface provided by XML System Services


The XML parser presents its services with two different language bindings, a C/C++
conforming set of services, and an assembler conforming set of services. Other programming
languages are not excluded from using XML System Services. You can use the Assembler
conforming services from both COBOL and PL/I without any restriction. In 9.2.1, “Assembler
interfaces” on page 132 we provide examples how these language can use the XML parser.
The C/C++ bindings can also be used directly from either COBOL or PL/I.

The interface between the application and the XML parser is a call/return structure. The
application invokes services provided by the XML System Services with the necessary
parameters. The called service then returns the results. Based on a return code and a reason
code provided by parser, the application will then control its flow. Data is exchanged in an
input, and an output buffer. More details on this can be found in 9.1.4, “Basic loop to manage
the input and output buffer” on page 119.

6.1.3 Buffer handling with XML System Services


z/OS XML System Services requires that its callers read in (acquire) the XML string and
provide additional XML strings as they are consumed by a parse. Additionally, applications
must handle the buffers that flow between the application and the parser. It is the
responsibility of the application to manage the size of these buffers according to its needs.
Use of large buffers might make the application easier to program but virtual memory
constraints might preclude the use of large buffers. Users should not assume that large
buffers will perform better than smaller buffers. Use of 4 K input buffers and 8 K output buffers
performs well for most documents.

Figure 6-2 on page 69 shows the buffers flowing between the application and the z/OS XML
System Services. We assume that every initialization has been done and the parse can take
place. For the moment we also assume that validation is not required. On the left side a XML
string is provided to the parse. In this example we assume that the complete document is too
large to be read into a single buffer. The reader function of the application fills a buffer and
advances this as parsing progresses. Logically, the reader slides a buffer window over the
XML string. The address of the position of the window is passed to z/OS XML System
Services routine gxlprs(), which is the parsing routine. Also passed to gxlprs() is the address
of an output buffer where the results are stored.

68 XML Processing Options on z/OS


Window
Buffer

Output Buffer
Reading

Application Filling

Acting

XML string to parse

Reson code
Return and
XML System Services

Figure 6-2 Buffers usages and flow in XML System Services

Upon return from the parser the application must be able to handle spanned buffers. Spanned
buffers occur because either the text in the input buffer is consumed, or the parsed data
stream completely fills the output buffer, but there is residual data left in the input buffer. In
these cases the z/OS XML System Services parser returns a conditional success return code
(XRC_WARNING), and a reason code that indicates which buffer caused the spanning
condition. The parser also informs the caller about the number of bytes not parsed or unused
in each buffer. The parser also advances pointers to the next byte to work on (input) or
unused by the parser (output).

After the parsed data stream is processed, the application should then handle the spanning
buffer, and can optionally manage the other buffer as well. The reason codes (in hexadecimal)
to look for are x”1301”, x”1303”, and x”1304”. More details can be found in 9.1.4, “Basic loop
to manage the input and output buffer” on page 119.

There is no requirement that the application needs to break the input buffer at logical
boundaries. That is, even if the current input buffer ends in the middle of a tag name, z/OS
XML System Services will handle that break and resume with the next byte when it is made
available. z/OS XML System Services handles buffers ending between bytes of a multi-byte
character. This keeps program design much simpler.

Chapter 6. Overview of parsing technologies on z/OS 69


6.1.4 General scheme for invoking z/OS XML System Services for parsing
In this section, we discuss the flow of events that take place when z/OS XML System
Services is invoked for parsing a document. We also discuss the concepts of optimized
schema representation (OSR) and string IDs.

General flowchart for buffer management


The flowchart in Figure 6-3 on page 72 explains the steps to be taken when invoking z/OS
XML System Services from an application program for both validating and non-validating
parsing. In either case, it is assumed that the preparatory part (initializing PIMA, OIMA, and
so forth) is done. This flowchart will concentrate on actual parsing with management of input
and output buffers.
1. Read XML from source (data set, MQ queue, HTTP, and so forth) into an input buffer in the
program storage.
2. Call GXL1PRS (GXL4PRS) to do the parse with this input buffer. A return code and a
reason is returned. When the return code is non-zero, actions need to be taken based on
the reason codes reported. Generally, it could mean replenishment of the input buffer,
re-allocation of the output buffer.
3. The flowchart considers only some of the possible reason codes. For other reason codes,
the application program must handle them as required.
a. Input Buffer ended (X”1301”)
This means z/OS XML System Services has parsed everything in the input buffer but
has not reached the end of the document. So it is asking the calling program to
replenish the input buffer. If the end of the document was reached (and the output
buffer was all fine), the return and reason codes from the parser would have been zero.
b. Output Buffer small (X”1302”)
This is returned when z/OS XML System Services is populating the allocated output
buffer with items that cannot be split (such as element name or attribute name), it has
reached the end of the output buffer and could go no further. This requires the
reallocation of output buffer.
i. From z/OS V1R11 onwards, the program can call the GXL1CTL (GXL4XCTL)
service with the XEC_CTL_QUERY_MIN_OUTBUF option to determine the
minimum size of the output buffer. The output buffer is re-allocated with this size as
reported by GXL1CTL (GXL4CTL) service. Then the parsing can proceed from the
point where it left off.
ii. Prior to z/OS V1R11, the parse instance must be terminated. Then, the PIMA has
to be re-initialized and GXL1PRS (GXL4PRS) is invoked with a likely estimate of the
output buffer. The parsing is initiated from the start of the document.
iii. This reason code is associated with return code 8.
iv. See z/OS XML System Services User’s Guide and Reference, SA23-1350 for more
information related to services, their parameters, and their return/reason codes.
v. See “An option to handle ‘Output Buffer small’ reason code (x’1302’)” on page 73
for an alternate way to handle this reason code.
c. Output Buffer ended (X”1303”)
This reason code is returned when z/OS XML System Services is writing into the
output buffer and encounters the end of the output buffer even though there is more to
parse in the input buffer. The z/OS XML System Services parser will update the
input_buffer_bytes_left parameter in the call to GXL1PRS (GXL4PRS) to indicate
the number of bytes in the input buffer that are yet to be processed. The output can be

70 XML Processing Options on z/OS


processed. Then a new output buffer can be allocated and provided to the parser with
the adjusted input buffer, or the same output buffer can be reused provided the output
is processed.
The input buffer can be provided to the parser in two ways.
• Let the parser parse the left-over bytes by re-adjusting the buffer. The input buffer
will now have the left over bytes from earlier parse with the length set to the value in
input_buffer_bytes_left parameter in the call to GXL1PRS (GXL4PRS).
• Replenish the input buffer to its limit such that the left over bytes are at the
beginning of the buffer. (This portion is shown in the flowchart in red color.)
d. Input and Output Buffer ended (X”1304”)
This is returned when both the buffers have been consumed. For example, the input
buffer has exhausted but the output buffer has been filled even before all the output has
been written. In this case, the input buffer should be replenished, the output buffer
processed. Then a new output buffer can be allocated and provided to the parser, or
the same output buffer can be reused provided the output is processed.

Chapter 6. Overview of parsing technologies on z/OS 71


Figure 6-3 Flowchart for invoking z/OS XML System Services

72 XML Processing Options on z/OS


An option to handle ‘Output Buffer small’ reason code (x’1302’)
As discussed in the previous section, reason code (x’1302’) is returned when the z/OS XML
System Services parser is not able to write to the output buffer because the output buffer is
too small in size. In releases prior to z/OS V1R11, the option was to terminate the parse
instance, acquire larger output buffer, re-initialize, and do the parsing from the starting of the
document. With z/OS V1R11 or later, an option is to call the GXL1CTL (GXL4CTL) service to
obtain the minimum output buffer size required. Using this size, a larger output buffer is
allocated, the PIMA is reset, and the XML document is parsed again from the beginning.

This section describes another way to parse a XML document (after the reason code x’1302’
was reported) from the point of the last successful parsing attempt. To implement this option,
there are two items that must be tracked after every successful parse. Note that a successful
parse also means a return code of 4. Firstly, the number of bytes (of the XML document)
parsed successfully is accumulated in an integer variable. Secondly, after every successful
parse, the PIMA is saved in a storage location similar to the original PIMA. This is done in
case the first attempt to parse the document fails with this reason code. If so, then the PIMA
to be used for subsequent retries is identical to the one returned by the initialization routine:
GXL1INI (GXL4INI).

At the point when x’1302’ is encountered, the following steps need to be taken:
1. From the beginning of the XML document (stored in a file, and so forth), read (but do not
process) as many bytes as saved in the integer variable for count of bytes successfully
processed until then.
2. Read the XML document further with as many bytes as required to fill the input buffer.
3. Pass the saved PIMA to the argument for PIMA of GXL1PRS (GXL4PRS).
4. Call GXL1PRS (GXL4PRS).

Before the parser is invoked, the arguments are set out as:
򐂰 PIMA is set to the saved PIMA
򐂰 input_buffer_addr is set to the input buffer having bytes from the document beyond the
point of last successful parse.

The flowchart for using this option is shown in Figure 6-4 on page 74. The dashed arrows
mean some more processing might be required but has been left out from this flowchart as it
is out of scope.

Chapter 6. Overview of parsing technologies on z/OS 73


Figure 6-4 One way of invoking z/OS XML System Services parser in case of x’1302’ reason code

74 XML Processing Options on z/OS


6.1.5 Optimized schema representation
z/OS XML System Services also provides validating parsing. When an XML document needs
to be parsed with validation, an optimized schema representation (OSR) must be made
available to the parser. This OSR is built from one or more XML schema definition (XSD) files
that define the validation that must done.

An OSR contains a binary representation of schema. Use of this binary representation allows
the validate process to be faster and more efficient. Schemas are sometimes long. Among
the other efficiencies brought by using OSRs, there is no need to parse the schema before
parsing the document you are trying to validate. OSRs are meant to be reused. That is, you
can load an OSR and validate many documents. You can validate only one document at a
time, of course.

z/OS XML System Services provides a tool to convert one or more XSD files into an OSR.
This tool is provided as a command for z/OS UNIX, and it can also be run from batch. A
callable service is also provided for generating OSRs through a program called gxluGenOSR.
This specific service is only available as a function for C/C++ users. There is no Assembler
service available to request this service. Further, the program from which the generator is
called must establish an environment in which Java can run. For an example of how to
achieve this, see 9.1.1, “Creating an OSR” on page 114.

6.1.6 Concept of StringID


String identifiers (StringIDs) are 4-byte integers which can be returned within the parsed XML
data stream in place of text values. XML string values such as namespace names and
abbreviations will appear hundreds, thousands, or even millions of times within an XML
document. Some complete names are quite long, even exceeding 250 characters.

By default, a z/OS XML System Services parse will return complete names each time, no
matter how many times they appear. By providing a User StringIDHandler exit routine, you
enable the z/OS XML System Services parser to replace those names with 4-byte StringIDs.
Use of 4-byte values in place of reoccurring text strings can substantially reduce the overall
size of the returned parsed data stream. Another advantage to StringIDs is that they are
much cheaper to search for and compare.

Note: Due to the amount of calls to the StringIDHandler exit caused by the number of
strings to handle and the potentially high number of searches in a StringIDTable adequate
means needs to be taken to ensure proper performance.

When StringIDs are in use, the application requesting the parse can, when it needs to, use
the provided string lookup routine to convert StringIDs to their original text value.

Note: The communication between the application and the StringIDHandler exit is
achieved through the system services parameter area. This area is not only a parameter
area, it can also be the storage for the StringIDTable. Examples in 9.1.6, “Get a StringID
exit working” on page 122 use this area in this manner. By this means the application can
provide the exit with a table already established when the OSR was generated or with
predefined string/StringID pairs.

Chapter 6. Overview of parsing technologies on z/OS 75


Figure 6-5 illustrates the use of a StringID exit routine.

XML System Services – String ID Exit Processing


Application XML System Services
Parse XML data
Call Parse <personnel-list>
<person >
<name>
John Doe
</name>
String ID Exit ... z/OS XML String ID Table
</person>
<person> personnel-list 3
Process <name>
person 7
parsed Jane Doe
App String ID Table </name> name 21
data ...
personnel-list 3 </person>
person 7 </Personnel-list>

name 21

PARSED DATA STREAM


Elem Elem Cdata John End . End Elem 7 ...
3 Elem 7 21 .
Doe Elem . Elem

Note: String IDs persist across multiple parses within a parser instance
Figure 6-5 String ID exit processing

When a parser instance is used to parse several documents, the StringID Table (and its string
IDs) persist until the end of the parser instance.

6.2 XML Toolkit on z/OS


This section discusses the XML Toolkit for z/OS. This toolkit is designed to provide a valuable
infrastructure component to assist you in creating, integrating, and maintaining your business
to business (B2B) solutions. It is based on cross-platform, open source code that is compliant
with industry standards. The current version as of this writing is V1R10.

6.2.1 Parsing with XML Toolkit for z/OS


The component for parsing in the toolkit is the XML Parser, C++ Edition. This is an
implementation on z/OS of the IBM XML4C parser. The XML4C parser is itself built on
Xerces, which is a collection of software libraries for parsing, validating, serializing, and
manipulating XML. It is an open source software being developed as an Apache Software
Foundation project.

The XML Parser, C++ Edition has implementations of SAX2 and DOM on z/OS V1R9 or later
but with slight alterations that allows it to use z/OS XML System Services. The support for
validation using XML Systems Services was provided in z/OS V1R10 onwards. Usage of
z/OS XML System Services can, in many cases, improve performance and allows for the
workload to be offloaded to zAAP speciality engine, if present. Thus, an application has two
choices for parsing. First, parse with the existing parser classes for which z/OS XML System
Services are not used. Second, parse with z/OS-specific parser classes where z/OS XML
System Services will be used. The flow for these options is depicted in Figure 6-6 on page 77.

76 XML Processing Options on z/OS


Figure 6-6 Flow of parsing with existing parsers (top) and z/OS-specific parsers (bottom)

Chapter 6. Overview of parsing technologies on z/OS 77


6.2.2 Parsing and validation with XML Toolkit on z/OS
Parsing with Validation of XML documents is also supported. See Figure 6-7. The following
requirements and restrictions apply:
򐂰 Requires XML Toolkit for z/OS 1.10 or higher
򐂰 The XML4C classes support DTD validation, but do not support z/OS XML or schema
validation

Figure 6-7 Validating parse with z/OS-specific classes

78 XML Processing Options on z/OS


Here are other considerations for the XML Toolkit for z/OS:
򐂰 The z/OS XML System Services C/C++ APIs that are called by the z/OS-specific parser
classes are compiled with XPLINK for best performance. It is strongly recommended to
use XPLINK when using the z/OS-specific parser classes. Mixing XPLINK and
non-XPLINK compiled code will result in a performance penalty. If the application program
cannot be compiled with XPLINK, then the non-XPLINK version of the parser must be
used.
򐂰 The z/OS-specific parser classes do not call the SAX startEntityReference and
endEntityReference. If the XML document has XML entities, these are resolved and
replaced with values by z/OS XML System Services as defined in the internal DTD. There
is no parse-time notification that this resolution and replacement has been done.
򐂰 Some schema-related features and properties are not supported or require settings when
using z/OS-specific parser classes.
򐂰 Caching of the schema grammar is not supported on z/OS-specific parser classes.
򐂰 The z/OS XML System Services is a namespace compliant parser. However, there is no
option to suppress this compliance, nor can the namespace be forced to be URI
conforming.
򐂰 When using z/OS-specific parser classes, the error messages displayed will have:
– Offset to the character in error instead of line and column number
– Return codes and reason codes are returned from z/OS XML System Services instead
of a descriptive error message
򐂰 The z/OS-specific parser do not support SAX1 or deprecated DOM. The SAX2XMLFilter
class is not supported and XMLDocumentHandler interface is not implemented in a
z/OS-specific parser

6.2.3 Parsing and source offsets with XML Toolkit on z/OS


When parsing it might be important to obtain the offset of XML elements in the source. This
feature (source offsets) is available on z/OS release 1.10 or higher. However, when using
source offsets, there are differences when using existing parser classes as opposed to
z/OS-specific parser classes. These differences are as follows:
򐂰 The z/OS-specific parser classes provide five APIs as opposed to one provided by existing
parser classes. The APIs provided by z/OS-specific parser classes are:
– getSrcOffsetStart()
– getSrcOffsetEnd()
– getSrcOffsetStart(index)
– getSrcOffsetEnd(index)
– getSrcOffsetNameEnd()
getSrcOffsetStart() is provided by existing parser classes.
򐂰 For attributes whose values are defaulted from a schema or internal DTD and values
substituted from ENTITY attribute in internal DTD, the existing parser classes return
source offset values from within the containing XML element. The z/OS-specific parser
classes will return the source offset from the beginning of the XML document.

Chapter 6. Overview of parsing technologies on z/OS 79


򐂰 During a progressive parse
– With existing parser classes, the control (when processing character data and element
after root element) is passed back to the application only when the data after the end of
the root element is processed. The z/OS-specific parser classes, instead, pass control
back for both end of root element and any subsequent character data or elements.
– Empty elements with no attributes, no namespace prefix and no defaulted content are
handled differently by existing and z/OS-specific parser classes. The former do not
return control to the application whereas the latter does.
– For a DOM tree, the existing parser classes will not store any DTD internal subset
information. The z/OS-specific parser classes will store any Processing Instruction (PI)
information.
򐂰 For the SAX2 endDocument event handler with a call to getSrcOffset(), the open source
parser classes include any characters following the root element; the z/OS-specific parser
classes do not.
򐂰 The z/OS-specific parser classes will return unpredictable results when querying XML
element declarations using:
– getURI()
– getId()
– isDeclared()
– isExternal()
– getCreateReason()
– getFormattedContentModel()
– getDOMTypeInfoUri()
– getDOMTypeInfoName()
򐂰 When parsing DTD elements, the offsets for start and end are reported differently by
existing parser and z/OS-specific parser classes. For the end of an element, the former
refers to the end of SYSTEM variant's value whereas the latter returns the offset of “>”,
which marks the end of the internal DTD element. For the start of an element, the former
refers to “[”, which marks the start of the internal DTD element, whereas the latter refers to
the offset of “<”, which marks the start of the internal DTD element.
򐂰 The internal subset of the DTD can be queried with the existing parser classes. This is not
the case with z/OS-specific parser classes.
򐂰 The Byte Order Mark (BOM) bytes are not considered by the existing parser classes. The
z/OS-specific parser classes include them (at offset 0 for first BOM byte).

6.3 Transforming XML documents with XML Toolkit for z/OS


In addition to the parser, the toolkit also includes the XSLT Processor, C++ Edition. The XSLT
Processor, C++ Edition is a port of the IBM XSLT4C XSLT processor (formerly known as
LotusXSL-C++). It is tested and packaged for use on z/OS. The processor is an
implementation of the W3C recommendations for XSL Transformations (XSLT) Version 1.0
and XML Path Language (XPath) Version 1.0. XSLT4C is based on open source code from
the Xalan Apache project of the Apache Software Foundation. It allows users to transform
XML documents into other formats.

80 XML Processing Options on z/OS


6.4 Newer features to handle XML on z/OS
A number of new XML-related features have become available over the last few years. The
following sections detail some important enhancements.

6.4.1 Enterprise PL/I for z/OS


Enterprise PL/I supported XML handling through the integrated routines PLISAXA, and
PLISAXB respectively. These were made available with version 3.1 of Enterprise PL/I. With
the announcement of version 3.8, the XML support within PL/I was further extended.

This is done through a new function, PLISAXC. This routine uses XML System Services
under the covers. It is similar to the older routines PLISAXA and PLISAXB. It supports:
򐂰 Documents larger than 2 GB
򐂰 Documents coded in UTF-8
򐂰 Namespaces

The application program provides an XML string in a buffer, and its length to PLIXSAXC. The
buffer does not need to contain a complete XML string. If the parser finds that the XML string
is incomplete, it will invoke an event to trigger the application program to provide more XML.

PLISAXC is not supported in AMODE(24).

6.4.2 Enterprise COBOL for z/OS


Recent enhancements to Enterprise COBOL for z/OS, with the release that introduced them,
include:
򐂰 XML PARSE to provide direct SAX-style parsing from within a COBOL program (V3R1)
򐂰 XML GENERATE to generate well-formed XML strings from COBOL data definitions
(V3R3)
򐂰 ENCODING clause for XML GENERATE, which provides the option for XML strings to be
generated in one of several supported codepages, rather than just UTF-16BE and the
program’s designated codepage (V4R1)
򐂰 WITH ATTRIBUTES clause for XML GENERATE, which provides the option to generate
XML strings in attribute-style rather than element-style (V4R1)
򐂰 WITH XML-DECLARATION clause for XML GENERATE, which provides the option to
prepend a standard XML declaration to the generated XML string (V4R1)
򐂰 WITH NAMESPACE ... NAMESPACE-PREFIX clauses for XML GENERATE, which
provides the option to generate XML strings using name spaces and name space prefixes
(V4R1)
򐂰 ENCODING clause for XML PARSE, which provides the option to specify the document’s
codepage (V4R1)
򐂰 Document containing attributes can be parsed using XML PARSE (V4R1)
򐂰 The RETURNING NATIONAL clause of XML PARSE allows parsed element values and
attribute values to be returned in UTF-16 format regardless of the document’s character
encoding. This can significantly simplify application design for applications that must parse
both Unicode-encoded documents and EBCDIC-encoded documents. (V4R1)

Chapter 6. Overview of parsing technologies on z/OS 81


򐂰 COBOL XML PARSE with validation (V4R2). V4R2 introduces the ability to parse with
validation. This option requires use of z/OS XML System Services [XMLPARSE(XMLSS)
compile option]. See Example 6-1.
򐂰 Element and attribute names with underscores (V4R2)

Enterprise COBOL for z/OS V4R2 accepts COBOL data item names and program names
with underscores. XML GENERATE automatically produces element and attribute names that
exactly match the source COBOL data names. By using underscore in the source COBOL
data names, it will automatically produce element and attribute names with underscores.

Example 6-1 COBOL XMLPARSE with validation


XML PARSE input-xml-data-item
VALIDATING WITH osr-data-item
PROCESSING PROCEDURE xml-event-handler-name
ON EXCEPTION {exception handling code goes here}
NOT ON EXCEPTION {all ok handling code goes here}
END-XML

SPECIAL-NAMES.
XML-SCHEMA schema-name1 IS ‘file name or path’,
schema-name2 IS ddname-or-environment-variable.

XML PARSE input-xml-data-item


VALIDATING WITH FILE schema-name1
PROCESSING PROCEDURE xml-event-handler-name
ON EXCEPTION {exception handling code goes here}
NOT ON EXCEPTION {all ok handling code goes here}
END-XML

osr-data-item, when provided, must contain a complete OSR. When referencing an OSR with
the FILE clause, the FILE clause must reference a SPECIAL-NAMES XML-SCHEMA entry.
XML-SCHEMA entries can reference a literal containing the file or path name, or they can
reference a ddname or environment variable name.

6.5 Parsing with pureXML


DB2 9 for z/OS introduced the XMLPARSE function. XMLPARSE allows you to parse or parse
and validate XML data. See 8.7, “Parsing with pureXML” on page 110 for more information.

82 XML Processing Options on z/OS


6.6 Storing XML within DB2 for z/OS
XML data is stored within DB2 within a column. XML columns must contain well-formed
documents. The simplest means storing XML data within a column using SQL INSERT or
SQL UPDATE with a host-variable. DB2 9 for z/OS provides the following six host variable
types for storing and retrieving XML data:
򐂰 SQL TYPE IS XML AS CLOB
򐂰 SQL TYPE IS XML AS BLOB
򐂰 SQL TYPE IS XML AS DBCLOB
򐂰 SQL TYPE IS XML AS CLOB_FILE
򐂰 SQL TYPE IS XML AS BLOB_FILE
򐂰 SQL TYPE IS XML AS DBCLOB_FILE

A CLOB host variable is assumed to be in the program’s default CCSID. XML is always stored
in UTF-8 (CCSID 1208). Therefore, XML within CLOB host variables will typically undergo a
conversion to UTF-8. When selecting XML into a CLOB, it will typically undergo a conversion
from UTF-8.

A DBCLOB host variable is assumed to be in UTF-16 CCSID (1200). These will also undergo
a conversion to and from UTF-16.

A BLOB host variable is binary and assumed unsafe for conversions. Therefore, a host
variable of type SQL TYPE IS XML AS BLOB is assumed to XML with character encoding
UTF-8.

CLOB_FILE, BLOB_FILE and DBCLOB_FILE are file reference locators. They allow you to
provide the data set name or path. When used for input, DB2 will read the contents of the
files. When used for output, DB2 will write to these files. XMLPARSE can parse data directly
from a file reference locator.

Example 6-2 illustrates storing XML data within a DB2 table.

Example 6-2 COBOL/SQL examples of storing XML within DB2


01 ebcdic-xml-text USAGE IS XML AS CLOB (20000).
01 utf-8-xml-text USAGE IS XML AS BLOB (20000).
01 utf-16-xml-text USAGE IS XML AS DBCLOB (20000).

EXEC SQL UPDATE tbl SET xml_col = :ebcdic-xml-text END-EXEC


EXEC SQL UPDATE tbl SET xml_col = :utf-8-xml-text END-EXEC
EXEC SQL UPDATE tbl SET xml_col = :utf-16-xml-text END-EXEC

For detailed information about XML host variable types, see the DB2 Version 9.1 for z/OS
Application Programming and SQL Guide. Additional information can be found in DB2 9
pureXML Guide, SG24-7315 and DB2 9: pureXML Overview and Fast Start, SG24-7298.

Chapter 6. Overview of parsing technologies on z/OS 83


84 XML Processing Options on z/OS
7

Chapter 7. Processing components,


relationships, and options
In this chapter we describe how multiple components can be combined and can interoperate.
We discuss the advantages and disadvantages of various combinations. We also list
scenarios where specific components provide substantial benefit.

© Copyright IBM Corp. 2009. All rights reserved. 85


7.1 Application programs and z/OS XML System Services
This section discusses application programs and their relationship to z/OS XML System
Services.

7.1.1 Enterprise COBOL for z/OS applications and z/OS XML System Services
COBOL applications can invoke an XML parse through the XML PARSE statement. See
Figure 7-1. The native COBOL parser will be invoked for programs compiled using the
XMLPARSE(COMPAT) option, while the z/OS XML System Services parser will be invoked by
programs using the XMLPARSE(XMLSS) option. Neither use of XML PARSE provides
document validation prior to V4R2. Using Enterprise COBOL V4R2 with the
XMLPARSE(XMLSS) compiler option plus the VALIDATING WITH phrase of the XML PARSE
statement will invoke the validating parser. When using XMLPARSE(XMLSS), the portion of
the processing performed by z/OS XML System Services will be offloaded to a zAAP when
one is present.

Alternatively, as Figure 7-1 shows, COBOL applications can invoke the z/OS XML System
Services parser through the provided assembler API using COBOL CALL ... USING or the
provided C API using COBOL CALL ... USING ... RETURNING .... Scenarios where
document validation is required could use this approach in place of, or in addition to, the use
of XML PARSE. When using z/OS XML System Services through APIs for parsing, the
application must navigate the intermediate format created by z/OS XML System Services.
Additionally, the application must manage both input and output buffers for z/OS XML System
Services.

COBOL
XML PARSE CALL

Native COBOL z/OS XML System z/OS XML System


parser Services Services

zAAP zAAP

Figure 7-1 COBOL and z/OS XML System Services combinations

The native COBOL XML parser is a high speed, low function option. It should be considered
when maximum performance is a significant requirement. The native COBOL parser’s
well-formedness checking does not identify all cases of improper XML form. The XML parser
cannot do document validation.

Use of the z/OS XML System Services parser through COBOL’s XML PARSE verb provides
much more functionality than the native COBOL parser.

86 XML Processing Options on z/OS


As a result, its speed is a little slower than the native COBOL parser. The z/OS XML System
Services parser does more thorough well-formedness checking than the integrated parser.
Additionally, benefits of using the XML System Services parsers are:
򐂰 Allows XML document text to be provided in pieces (buffers), which might be required for
large documents
򐂰 Provides for simpler application programming when documents contain variations in
character encoding
򐂰 Parses documents containing namespaces.
򐂰 Documents encoded using UTF-8 can be parsed directly, rather than first being converted
to UTF-16BE.

7.1.2 Enterprise PL/I for z/OS programs and XML System Services on z/OS
Enterprise PL/I for z/OS provides three SAX-style parsing routines (see Figure 7-2):
򐂰 PLISAXA
򐂰 PLISAXB
򐂰 PLISAXC

PLISAXC uses the z/OS XML System Services parser while PLISAXA and PLISAXB use
PL/I-provided routines. PLISAXC is the only built-in routine with the option of offloading most
of the XML parsing work to a zAAP.

Alternatively, PL/I applications can invoke the z/OS XML System Services parser using the
provided assembler or C API. Scenarios where document validation is required could use this
approach in place of, or in addition to, the use of PLISAXC. When using z/OS XML System
Services for parsing, the application must navigate the intermediate format created by z/OS
XML System Services. The application must also manage both input and output buffers for
the z/OS XML System Services.

PL/I
CALL

PLISAXA PLISAXB PLISAXC z/OS XML


XML parser XML parser XML parser System
Services

z/OS XML zAAP


System
Services

zAAP

Figure 7-2 PL/I and z/OS XML System Services combinations

Chapter 7. Processing components, relationships, and options 87


7.1.3 Assembler, C, and XML System Services on z/OS
The z/OS Assembler has no built-in XML parser. z/OS XML System Services provides an
assembler compatible interface. XML parsing is eligible for offloading to a zAAP.

C can use either the z/OS XML System Services assembler interface or the z/OS XML
System Services C++ interface depending upon whether XPLINK is needed.

7.1.4 C++ and z/OS XML System Services


C++ can invoke z/OS XML System Services directly through the provided C/C++ interface.
XML parsing is eligible for offload to a zAAP/zIIP.

The XML Toolkit for z/OS provides to C++ applications both DOM and SAX interfaces. When
the zSAX2XMLReader virtual class is used, z/OS XML System Services will be used and
XML parsing is eligible for offload to a zAAP/zIIP.

7.1.5 Software outside the usual scope of a TCB


User programs such as a batch program or even a CICS transaction program are represented
within z/OS by a task control block (TCB). A TCB with many other control blocks related to it
describes a complex environment. Therefore TCB creation and termination are costly.
Furthermore a TCB itself can only represent work within one address space. For short-lived
services or functions that need to span multiple address spaces, z/OS offers to use service
request blocks (SRB). An SRB that spans multiple address spaces is also called an enclave
SRB. Together with TCBs, SRBs are the primary units of work that z/OS knows and
dispatches on a CP (or zAAP or zIIP).

In case your software has the requirement to run under control of an SRB, you need to fulfill
particular requirements. One requirement is that you cannot use program code that is
dependent on Language Environment. This can be achieved by writing a C program and
using the bare metal C code variant of it. Another option is to use Assembler. In either case,
you can use z/OS XML System Services in such an environment because these services are
not using the Language Environment.

7.2 When to use the XML Toolkit


In this section we list scenarios where use of the XML toolkit functions is beneficial.

7.2.1 XML document transformation


The simplest and most extensible means on System z to accomplish XML transformation is to
use the XML toolkit with its XSLT processor (or the similar XSLT processor support in Java).
Providing an input file and XSL style sheet input file will produce a transformed output file.
XML transformations include:
򐂰 XML to XML
򐂰 XML to HTML
򐂰 XML to text

88 XML Processing Options on z/OS


7.2.2 Implementing C or C++ applications using XML parser classes
New and existing C/C++ applications that require XML parsing can use the Toolkit’s XML4C
parser classes. When implementing existing applications from non-System z to System z
using the z/OS special parser classes, some application changes might be required.

7.2.3 Invoking the XML Toolkit XSLT Processor from within COBOL-PL/I
applications

Transforming XML input prior to parsing


While COBOL and PL/I provide built-in statements and subroutines for XML generation and
parsing, they are not well equipped for XML transformations. An application that requires
transformation of incoming XML before the application can parse it might benefit from
invoking the toolkit to achieve transformation and parsing the transformation result. See
Figure 7-3.

XML Toolkit
XML Transformed COBOL, PL/I
for z/OS
XML parse
XSLT processor

Figure 7-3 Invoking the XML toolkit from within COBOL-PL/I, single document input

To process many documents, the application could iteratively position non-transformed XML,
invoke the toolkit, and parse the result, as shown in Figure 7-4.

XML XML XML XML XML

COBOL, PL/I
Application

Position next XML


Document

XML Toolkit
Invoke XSLT for z/OS
XSLT processor

Transformed
Parse XML

Figure 7-4 Invoking the XML Toolkit from within COBOL-PL/I for multiple input documents

Transforming XML after generation


An application might need to create a generic XML document, but transform the output to the
receiver’s specifications prior to delivering the final document. The application can generate
the generic XML document, acquire the appropriate XSL specification file, invoke the toolkit,
and position the transformed document as the final output.

Chapter 7. Processing components, relationships, and options 89


XML Toolkit
COBOL, PL/I Transformed
XML for z/OS
parse XML
XSLT processor

Figure 7-5 Invoking the XML toolkit from within COBOL-PL/I for a single output document

7.2.4 Invoking the XML Toolkit Parser from within COBOL-PL/I applications
COBOL and PL/I applications can invoke the XML Toolkit for z/OS Parser, C++ Edition. It is a
good practice to invoke a C glue routine to invoke the appropriate C error handling semantics.
Examples of COBOL calling the toolkit for z/OS Parser with a C routine are available within
the XML Toolkit for z/OS User’s Guide, SA22-7932.

7.3 When to use the z/OS XML System Services parsers


Using the native COBOL and PL/I parsers is a good practice when they provide all the
needed functionality. However, the application might require functions available with z/OS
XML Systems Services that are not in the native parsers. In these scenarios, high level
languages can invoke z/OS XML System Services either through language features or using
APIs.

7.3.1 When to use the z/OS XML System Services parser


Some design scenarios require use of the z/OS XML System Services parser rather than the
native parser. There are also scenarios where use of the z/OS XML System Services parser
provides benefits, though it is not required.
򐂰 Large documents
The native COBOL parser requires the entire document be available in contiguous
memory. The z/OS XML System Services parser will accept documents in one or more
buffers.
򐂰 Document text arrives in pieces
When whole documents are constructed from multiple segments (MQ messages, HTTP
requests, sockets, file records, and so forth), it might be easier to provide each segment
separately to the z/OS XML System Services parser rather than merge multiple segments
into a single large memory area for the native COBOL parser.
򐂰 Document is provided in UTF-8
z/OS XML System Services parses a document encoded in UTF-8 directly. The native
parser requires converting the entire document from UTF-8 to UF-16 prior to parsing.
򐂰 Document containing namepaces
The z/OS XML System Services parser parses namespaces. As of Enterprise COBOL for
z/OS V4R1, the native parser does not parse namespaces.
򐂰 Documents in unpredictable and mixed code pages
When a program has to handle documents in different code pages, the use of z/OS
XMLSystem Services enables the use of the COBOL RETURNING NATIONAL clause.
Specifying RETURNING NATIONAL causes all parsed text to be returned in UTF-16,
regardless of the actual document encoding. This can significantly simplify program

90 XML Processing Options on z/OS


design as the program can work with document values exclusively in UTF-16, rather than
EBCDIC values for documents using one of the supported EBCDIC code pages and
UTF-16 for documents using UTF-16.

7.3.2 When to use the COBOL native parser


A COBOL application for which speed is the most important factor would benefit from using
the native COBOL parser instead of the z/OS XML System Services parser.

7.3.3 When to use the z/OS XML parser rather than the PL/I native parser
Some design scenarios require use of the z/OS XML System Services parser rather than the
native parser. There are also scenarios where use of the z/OS XML System Services parser
provides benefit, though it is not required.
򐂰 Large documents
The PLISAXA parser requires the entire document be available in contiguous memory.
The z/OS XML System Services parser will accept documents in one or more buffers.
PLISAXB requires the entire document be available in a file and places a 2 GB limit upon
the total text length. Additionally, PLISAXB reads the entire content of the file into memory.
Therefore, there must be sufficient memory available to contain the entire document.
z/OS XML System Services’ multi-buffer arrangement allows processing of large
documents.
򐂰 Document text arrives in pieces
When whole documents are constructed from multiple segments (MQ messages, HTTP
requests, sockets, file records, and so forth), it might be easier to provide each segment
separately to the z/OS XML System Services parser rather merge multiple segments into
a single large memory area for the native PL/I parser.
򐂰 Document is provided in UTF-8
The z/OS XML System Services parser processes documents encoded in UTF-8 directly.
The native PL/I parser requires converting the entire document from UTF-8 to UF-16 prior
to parsing.
򐂰 Document containing namepaces
The z/OS XML System Services parser parses namespaces. As of Enterprise PL/I for
z/OS V3R8, the native parser does not parse namespaces.

7.3.4 When to change from COBOL and PL/I native parsers to z/OS XML
System Services parsers
Changing existing applications to z/OS XML System Services parsers should be considered
when sufficient zAAP/zIIP eligible work exists to justify purchasing zAAP or zIIP engines. Use
of z/OS XML System Services parsers will increase the benefit gained from the speciality
engines.

There are some differences between the output of z/OS XML System Services parsers and
non-z/OS XML System Services parsers. Application changes are sometimes required to
change from one to the other. For example, for COBOL there are detailed instructions on how
to migrate from the native parser to XML System Service parser in Enterprise COBOL for
z/OS Version 4.2 Compiler and Runtime Migration Guide, GC23-8527.

Chapter 7. Processing components, relationships, and options 91


92 XML Processing Options on z/OS
8

Chapter 8. How to parse XML

© Copyright IBM Corp. 2009. All rights reserved. 93


8.1 Parsing Using z/OS XML System Services
z/OS XML System Services provides two basic approaches for non-validating parsing and
five approaches for validating parsing.

8.1.1 Non-validating Parsing using z/OS XML System Services


Here are three illustrations of non-validating parse.

Simple non-validating parsing


The simplest approach to using z/OS XML System Services requires that the application
initialize z/OS XML System Services, then request a parse. z/OS XML System Services will
return the parsed data stream and the application will process the parsed data stream. See
Figure 8-1.

Application z/OS XML


Invoking XML parsed
XML Parse data stream

Figure 8-1 Simple non-validating parsing using z/OS XML System Services

Non-validating parsing with String IDs


String IDS are 4-byte numeric values provided in place of frequently occurring string values.
The XML parsed data stream returned by z/OS XML System Services can be substantially
smaller when String IDs are returned. Additional processing efficiency can be gained by
comparing and searching 4-byte String ID values rather than the longer string values. See
Figure 8-2.

StringID Table User


String
up Handler
ok
lo
ll
ca
Application
XML Invoking z/OS XML
Parse
smaller
XML parsed
data stream

Figure 8-2 Non-validating parsing with z/OS XML System Services using String IDs

z/OS XML System Services will invoke the user-provided User String Handler routine for each
unique text value. The User String Handler searches the StringID table and returns the
assigned StringID if one already exists, or adds the new string to the StringID table and
returns the newly assigned StringID value.

While processing the XML-parsed data stream, the application can use the GXLSYM31
(GXLSYM64) StringID service (lookup) routine to retrieve the text string value for a given
StringID.

94 XML Processing Options on z/OS


Non-validating parsing with an initial predefined set of StringID values
Normally, StringID values are assigned as each unique text string is encountered within the
document. Consequently, a particular string value might be assigned a StringID value of 10 in
one document and 200 in another document.

One of the advantages of providing your own User String Handler routine is that it allows you
to use a predefined set of StringID assignments. This allows a set of business applications to
use the same StringID values for the same text values in every XML document they parse.
See Figure 8-3.

StringID Table User


String Predefined
up Handler StringID values
ok
lo
ll
ca
Application
XML Invoking z/OS XML
Parse
smaller
Note 1 XML parsed
data stream

Figure 8-3 Non-validating z/OS XML System Services parsing with a predefined set of String ID values

Note: Use of predefined StringID values can provide substantial processing efficiency for
some parsing processes. It can be used to avoid StringID to Text lookup calls and facilitate
navigation of the XML parsed data stream and sparse parsing.

Sparse parsing is the act of quickly isolating only those portions of the XML parsed data
stream which are germane to the business process. This in contrast to navigating the
entire parsed data stream.

8.1.2 Validating parsing using z/OS XML System Services


Parsing with document validation requires the application to load an OSR version of the XML
schema definitions (XSD files). The creation of the OSR and use of the OSR for validation
can occur in one step or two. The two-step process is often used so that the OSR can be
stored and used again later. With both one-step and two-step processes, after an OSR is
loaded, it can be used to validate one to many documents.

After illustrating basic two-step and one-step processes, we will discuss three more advanced
models that use additional features of the z/OS XML System Services parser.

Two-step process
The two-step process separates the creation of the OSR from the use of the OSR. To create
an OSR, the application must initialize the OSR generator environment, load the XSD files
and generate the OSR. The resulting OSR can be stored and used as needed.

Other steps can then load the OSR, initialize the parse environment, make the XML string
available, request a parse, and process the returned XML parsed data stream. When loaded,
the OSR can be used over and over again.

Chapter 8. How to parse XML 95


The OSR automatically includes a String ID table which is used during parse operations. See
Figure 8-4.

Load Schema z/OS XML xsd


schema

StringID table
Generate OSR z/OS XML

OSR
StringID
Write OSR table
Step 1
Step 2
Read and Load OSR z/OS XML

Note 2

XML Parse with validation z/OS XML


XML parsed
Process data stream Data stream

Figure 8-4 Two-step validating parse

Note: Document parsing performance is improved for strings within the XML document
which appear within the OSR.

You do not need to provide a User String Handler to the OSR generation step to obtain the
benefits of using a String ID table within the OSR. The OSR generator provides a default
String Handler that builds the appropriate String ID table. The use and benefits of providing
your own User String Handler within OSR generation will be discussed in “Validating parsing
with predefined StringIDs returning StringIDs” on page 98.

One-step process
The one-step process combines all the steps from the two-step process and provides
identical results and benefits. See Figure 8-5 on page 97.

96 XML Processing Options on z/OS


Load Schema z/OS XML XSD

StringID table
Generate OSR z/OS XML

OSR
Write OSR StringID
table

Load (point to) z/OS XML


OSR

XML Parse with validation z/OS XML


XML parsed
Process data stream Data stream

Figure 8-5 One-step validating parse

Document parsing performance is improved for strings within the XML document that appear
within the OSR.

Validating parsing with predefined String ID assignments


By providing your own User String Handler routine, you can use predefined String ID
assignments within the OSR. Not only will parse performance benefit from the String ID table
within the OSR, but the application can benefit from consistent String ID values for every
document. See Figure 8-6.

XSD

OSR
OSR
StringID Complete OSR
table GENERATE
StringID table
call

User
Predefined
String
StringID
Handler
assignments
Load OSR z/OS XML

Parse with z/OS XML


XML Validation

Process stream XML parsed


data stream

Figure 8-6 Validating parse with predefined String ID assignments

Chapter 8. How to parse XML 97


With this approach the XML parsed data stream will not contain String IDs. However,
document parsing performance is still improved for strings within the XML document that
appear within the OSR.

Validating parsing with predefined StringIDs returning StringIDs


All of the benefits of the preceding approaches can be combined by providing a User String
Handler routine for the OSR generate and XML parse. See Figure 8-7.

XSD

OSR
OSR
StringID Complete OSR
table GENERATE
StringID table

call
StringID Table User
User
String
String Predefined
lookup

Handler
Handler StringID
assignments
z/OS XML Load OSR
l
c al

Parse with z/OS XML


XML Validation
Smaller
Process stream XML parsed
Data stream

Figure 8-7 Validating parse with predefined String ID assignments returning String IDs

Use of a User String Handler during parsing provides a smaller XML parsed data stream. It
includes String IDs for the XML string and names appearing within the XSD schema. Use of a
predefined StringID assignment within the User String Handler allows consistent assignment
of specific text strings to specific String ID values.

When using a String Handler for parsing we suggest you write your own and use it for both
parsing and OSR generation. Two different executable modules are required. OSR generation
expects the String Handler routine to use OS linkage conventions and establish its own
dynamic storage. The parser requires the String Handler routine to use special prolog and
epilog code for establishing dynamic storage. Language Environment conforming routines
cannot be used for a parser-driven String Handler routine because Language Environment
routines cannot execute in enclave-SRB mode. It is possible to create both executable
modules from a single source module. For information regarding creating these executables,
see 9.1.6, “Get a StringID exit working” on page 122.

Validating parsing returning predefined StringIDs and OSR’s string ID


table
One additional feature of validating parsing might be advantageous to some parsing needs.
The String ID table from the OSR document can be extracted and used while processing the
parsed XML data stream. See Figure 8-8 on page 99.

98 XML Processing Options on z/OS


XSD

OSR
OSR
StringID Complete OSR
table GENERATE
StringID table

call
StringID Table User
User
String
String Predefined

lookup
Handler
Handler StringID
assignments
z/OS XML Load OSR

call
z/OS XML Extract String
OSR’s
Table
StringID Table
Parse wih z/OS XML
XML Validation XML parsed
Data stream
Process data stream

Figure 8-8 Validating parse returning predefined String IDs and the OSR’s String ID table

8.2 XML Toolkit for z/OS


With the XML Toolkit for z/OS you have a number of alternative approaches to the parsing
process. Your must consider these possibilities before starting the development process for
your application:
򐂰 SAX or DOM processing
If your application needs to inspect in the XML document more than once, choose DOM
processing. Otherwise the SAX method will be more efficient and have less central
storage demands.
򐂰 General or z/OS-specific Parser Classes
There are minor differences between the two sets of parser classes, but if possible, use
the z/OS-specific classes for better performance and cost for a non-validating parse. For
more information about the differences, refer to V1.10 XML Toolkit User's Guide,
SA22-7932.
򐂰 Programming language
XML Toolkit for z/OS is coded in C++. To gain full benefit of the package you need
application developers with a deep understanding of C or C++. You can combine existing
application programs in other languages, such as COBOL or PL/I with the Toolkit package,
but you still need C or C++ knowledge.

Chapter 8. How to parse XML 99


򐂰 XPLINK
If you choose to use the z/OS-specific parser classes, it will use z/OS XML System
Services under the covers, which is compiled using XPLINK. This forces you to compile
you own modules in XPLINK to avoid performance degradation.
If you do not use the z/OS-specific parser classes, the XML Toolkit for z/OS provides you
with both XPLINK and non-XPLINK versions of the underlying modules. This enables you
to use the version most appropriate to the application in question.
򐂰 MVS or UNIX Environment
XML Toolkit for z/OS is running on both environments and capable using both HFS, zFS,
or MVS file systems

8.2.1 SAX parsing


The toolkit SAX parser reads the XML document from a file and passes the elements in the
document to your application one by one through the callback routine. The application must
handle initialization of both XML4C and parser options and handle a proper termination when
the parse is completed.

Figure 8-9 shows the main program flow for a SAX2 parser application and the corresponding
code.

Parsing function Coding sample

Initialize XML4C system XMLplatformUtils::Initialize();

SAX2XMLReader* parser =
Create an instance of the parser
XMLReaderFactory::createXMLReader();

SAX2CountHandlers handler;
Declare and register Handlers parser -> setContentHandler(&handler);
parser -> setErrorHandler(&handler);

parser -> setFeature


(XMLUni::fgSAX2CoreNoameSpaces,doNamespaces);
Set parser features parser -> setFeature
(XMLUni::fgSAX2CoreNameSpacePrefixes,
namespacesPrefixes);

Start Parsing parser -> parse(xmlFile);

Clean up Delete parser;

Terminate XML4C system XMLplatformUtils::Terminate();

Figure 8-9 SAX parsing main program overview

For more detailed information, refer to the following resources:


򐂰 XML Toolkit for z/OS User’s Guide, SA22-7932-07
򐂰 API documentation contained in the XML Parser, C++ Edition product directory (Ask your
systems programmer where these files are placed on your installation)

100 XML Processing Options on z/OS


You control the parsing by writing your own document handler and giving the parser the name
of the handler. The default document handler delivered with the system can be used as a
starting point and subsequently enhanced with your homegrown handler methods.

The document handler is the main interface in a SAX application. Figure 8-10 shows how the
SAX parser transfers information to the application by calling methods in the document
handler.

Parsing function Document handler method


called

Start Parsing parser -> parse(xmlFile);

The XML4C parser invokes StartDocument


the document handler routine StartElement
for each event in the XML string StartElement
Characters
The feature invoked EndElement
signals the document handler StartElement
which event is occurred. Characters
EndElement
If the parser finds an error in the XML StartElement
Document, information is communicated Characters
to the application using the error handler EndElement
EndElement
EndDocument

Figure 8-10 Overview of document handler in SAX parsing

Example 8-1 describes the different interfaces to the document handler. The SAX parser
application must be able to use the most important of these interfaces to process the XML
documents.

Example 8-1 Document handler interface description


Interface to the Content handler

virtual void characters (const XMLCh *const chars, const XMLSize_t length)=0
Receive notification of character data.

virtual void endDocument ()=0


Receive notification of the end of a document.

virtual void endElement (const XMLCh *const name)=0


Receive notification of the end of an element.

virtual void ignorableWhitespace (const XMLCh *const chars, const XMLSize_t


length)=0
Receive notification of ignorable whitespace in element content.

virtual void processingInstruction (const XMLCh *const target, const XMLCh *const
data)=0
Receive notification of a processing instruction.

virtual void resetDocument ()=0

Chapter 8. How to parse XML 101


Reset the Docuemnt object on its reuse.

virtual void setDocumentLocator (const Locator *const locator)=0


Receive an object for locating the origin of SAX document events.

virtual void startDocument ()=0


Receive notification of the beginning of a document.

virtual void startElement (const XMLCh *const name, AttributeList &attrs)=0


Receive notification of the beginning of an element.

8.2.2 DOM parsing


The Toolkit DOM parser reads the XML document from a file and builds a tree structure in
memory that reflects the structure of the received XML document. After the tree structure is
built, control is given to the application for further processing. The application is now able to
inspect the tree using the DOMNode API. The API allows the application to guide through the
tree from root to leaf. The application will be able to return to specific nodes if necessary.

The DOM parsing has the same main flow as the SAX parsing regarding initialization and
termination. Figure 8-11 shows the main program flow for a DOM parser application and the
corresponding C++ code.

Parsing function Coding sample

Initialize XML4C system XMLplatformUtils::Initialize();

XercesDOMParser * parser =
Create an instance of the parser new XercesDOMParser();

DOMtreeErrorReporter * errReporter =
new DomTreeErrorReporter();
Declare and create Handlers DOMWriter * theSerializer =
((DOMImplementationLS*)impl)->createDOMWriter();

parser -> setValidationScheme(gValScheme);


Set parser features and
parser -> setDoSchema(gDoSchema);
register handlers with parser parser -> setErrrorHandler(errReporter);

Parse the document and


parser -> parse(gxmlFile);
build the DOM tree

Get DOM representation and DOMNode * doc = parser->getDocument();


parse it on to Writer theSerializer->writeNode(myformTarget, *doc);

Clean up and Delete parser; Delete errReporter;


Terminate XML4C system XMLplatformUtils::Terminate();

Figure 8-11 DOM parsing

The DOM parser application must navigate through the DOM tree. Example 8-2 on page 103
illustrates this task. Example 8-2 on page 103 shows the XML document used.

102 XML Processing Options on z/OS


Example 8-2 XML Document
<?xml version="1.0" encoding="UTF-8" ?>
<library>
<book language="English">
<author country="UK">Lewis Carrol</author>
<title>Alice's Adventures in Wonderland</title>
<year>1865</year>
<ISBN>0000123456</ISBN>
</book>
<book language="English">
<author country="US">Mike Ebbers</author>
<author country="DE">Hans-Dieter Mertiens</author>
<title>XML Processing on z/OS</title>
<year>2009</year>
<ISBN>0000123458</ISBN>
</book>
</library>

The parsing statement in the application built the DOM tree in memory. The relationship
between the elements is shown in Figure 8-12. The entire document tree is not detailed here.

Root element
<library> Siblings
Parent

Child

CharacterData Attribute Element Element


English “language” <book> <book>

Attribute Element Element Element Element


“country” <author> <title> <year> <ISBN>

CharacterData CharacterData CharacterData CharacterData CharacterData


UK Lewis Carrol Alice’s Adventure 1865 0000123456
in Wonderland

Attribute Element Element Element Element


“country” <author> <title> <year> <ISBN>

CharacterData CharacterData
US Mike Ebbers CharacterData CharacterData CharacterData
XML processing 2009 0000123458
Attribute Element on z/OS
“country” <author>

CharacterData CharacterData
DE Hans-Dieter Mertiens

Figure 8-12 DOM tree

The figure details the relation from element to element and the relation between an element
and the corresponding value and eventual attributes. To navigate through the DOM tree, the
application must use the different interfaces to DOMNode to ensure all needed information in
the XML document is handled.

Chapter 8. How to parse XML 103


Example 8-3 describes the different interfaces to DomNode, the DOM parser application must
be able to handle the most important interfaces to navigate through the XML documents.

Example 8-3 DOMNode interface description


Interface to the DOMNode

Functions introduced in DOM Level 1

virtual const XMLCh * getNodeName () const =0


The name of this node, depending on its type; see the table above.

virtual const XMLCh * getNodeValue () const =0


Gets the value of this node, depending on its type.

virtual NodeType getNodeType () const =0


An enum value representing the type of the underlying object.

virtual DOMNode * getParentNode () const =0


Gets the parent of this node.

virtual DOMNodeList * getChildNodes () const =0


Gets a DOMNodeList that contains all children of this node.

virtual DOMNode * getFirstChild () const =0


Gets the first child of this node.

virtual DOMNode * getLastChild () const =0


Gets the last child of this node.

virtual DOMNode * getPreviousSibling () const =0


Gets the node immediately preceding this node.

virtual DOMNode * getNextSibling () const =0


Gets the node immediately following this node.

virtual DOMNamedNodeMap * getAttributes () const =0


Gets a DOMNamedNodeMap containing the attributes of this node (if it is an DOMElement) or
null otherwise.

virtual DOMDocument * getOwnerDocument () const =0


Gets the DOMDocument object associated with this node.

virtual DOMNode * cloneNode (bool deep) const =0


Returns a duplicate of this node.

virtual DOMNode * insertBefore (DOMNode *newChild, DOMNode *refChild)=0


Inserts the node newChild before the existing child node refChild.

virtual DOMNode * replaceChild (DOMNode *newChild, DOMNode *oldChild)=0


Replaces the child node oldChild with newChild in the list of children, and returns the
oldChild node.

virtual DOMNode * removeChild (DOMNode *oldChild)=0


Removes the child node indicated by oldChild from the list of children, and returns it.

virtual DOMNode * appendChild (DOMNode *newChild)=0


Adds the node newChild to the end of the list of children of this node.

virtual bool hasChildNodes () const =0

104 XML Processing Options on z/OS


This is a convenience method to allow easy determination of whether a node has any
children.

virtual void setNodeValue (const XMLCh *nodeValue)=0


Sets the value of the node.

Functions introduced in DOM Level 2.

virtual void normalize ()=0


Puts all DOMText nodes in the full depth of the sub-tree underneath this DOMNode,
including attribute nodes, into a "normal" form where only markup (e.g., tags, comments,
processing instructions, CDATA sections, and entity references) separates DOMText nodes,
i.e., there are neither adjacent DOMText nodes nor empty DOMText nodes.

virtual bool isSupported (const XMLCh *feature, const XMLCh *version) const =0
Tests whether the DOM implementation implements a specific feature and that feature is
supported by this node.

virtual const XMLCh * getNamespaceURI () const =0


Get the namespace URI of this node, or null if it is unspecified.

virtual const XMLCh * getPrefix () const =0


Get the namespace prefix of this node, or null if it is unspecified.

virtual const XMLCh * getLocalName () const =0


Returns the local part of the qualified name of this node.

virtual void setPrefix (const XMLCh *prefix)=0


Set the namespace prefix of this node.

virtual bool hasAttributes () const =0


Returns whether this node (if it is an element) has any attributes.

Functions introduced in DOM Level 3.

virtual bool isSameNode (const DOMNode *other) const =0


Returns whether this node is the same node as the given one.

virtual bool isEqualNode (const DOMNode *arg) const =0


Tests whether two nodes are equal.

virtual void * setUserData (const XMLCh *key, void *data, DOMUserDataHandler *handler)=0
Associate an object to a key on this node.

virtual void * getUserData (const XMLCh *key) const =0


Retrieves the object associated to a key on a this node.

virtual const XMLCh * getBaseURI () const =0


The absolute base URI of this node or null if undefined.

virtual short compareDocumentPosition (const DOMNode *other) const =0


Compares the reference node, i.e.

virtual const XMLCh * getTextContent () const =0


This attribute returns the text content of this node and its descendants.

virtual void setTextContent (const XMLCh *textContent)=0


This attribute removes any possible children this node may have and, if the new string is
not empty or null, replaced by a single DOMText node containing the string this attribute
is set to.

Chapter 8. How to parse XML 105


virtual const XMLCh * lookupPrefix (const XMLCh *namespaceURI) const =0
Look up the prefix associated to the given namespace URI, starting from this node.

virtual bool isDefaultNamespace (const XMLCh *namespaceURI) const =0


This method checks if the specified namespaceURI is the default namespace or not.

virtual const XMLCh * lookupNamespaceURI (const XMLCh *prefix) const =0


Look up the namespace URI associated to the given prefix, starting from this node.

virtual void * getFeature (const XMLCh *feature, const XMLCh *version) const =0
This method makes available a DOMNode's specialized interface.

Non-standard Extension

virtual void release ()=0


Called to indicate that this Node (and its associated children) is no longer in use and
that the implementation may relinquish any resources associated with it and its associated
children.

A DOM parser application is more complex and consumes more memory (to hold the entire
document in its internal tree representation) than a SAX parser application. But it has the
advantage that the applications are able to search the DOM tree without reading all elements
or attributes, plus the possibility to reenter specific elements.

8.3 COBOL
The z/OS XML System Services parser will be used for programs using XML PARSE and
compiled with the XMLPARSE(XMLSS) compile option. For an example of XML PARSE, see
Enterprise COBOL for z/OS Version 4.2 Programming Guide, SC23-8529.

The z/OS XML System Services parser can also be called directly from a COBOL application.
For an example of COBOL calling z/OS XML System Services directly, see B.4, “Enterprise
COBOL program to query XML document declaration” on page 180 and B.5, “C program to
query XML document declaration” on page 183’.

8.4 PL/I
The z/OS XML System Services parser will be used for programs using PLSIAXC.

The z/OS XML System Services parser can also be called directly from a PL/I application. For
an example of PL/I calling z/OS XML System Services directly, see 7.1.2, “Enterprise PL/I for
z/OS programs and XML System Services on z/OS” on page 87.

8.5 CICS Web Services


When CICS is a service provider, the XML provided by the requester is received in the Web
services interface and the data is transformed in the pipeline handlers before it is passed to
the business application in a traditional language structure. Figure 8-13 on page 107 gives an
overview of CICS as a service provider.

106 XML Processing Options on z/OS


CICS TS
User transaction

SOAP Response CSOL Pipeline


Service IP-Socket
Requester SOAP Request Listener
Handler
CWXN
Handler

Pipeline
Handler
Handler

Handler

Handler Business
Logic

Figure 8-13 CICS as a Service Provider

CICS Web Services automatically starts the CICS transaction related to the XML message.
The application program receives the data in the corresponding channel and reads in the data
container by container.

The business application replies to the requester by placing the reply data in containers in the
same channel the request was received. Data is then transformed to XML by the pipeline
according to the information in the WSBind file.

8.5.1 CICS Web Services Assistant


This utility provide you with a tool to generate the wsbind file that contains information to
make the transformation from language structure to XML or from XML to language structure.

The tool contains two programs:


򐂰 DFHLS2WS, which constructs a WSDL document from a existing language structure
򐂰 DFHWS2LS, which constructs a language structure from a WSDL

Both programs also create the WSBIND file. The tool contains two programs (see Figure 8-14
on page 108).

Chapter 8. How to parse XML 107


Bottom up
CICS HFS
PDS
Web Services
Assistant WSBind
Language
Structure
Data mapping WSDL
DFHLS2WS

Top down
PDS

HFS CICS Language


Web Services Structure
WSDL Assistant
Schema
HFS
DFHWS2LS
WSBind

Figure 8-14 CICS Web Services Assistant

The Web Services Assistant supports COBOL, PL/I, C and C++.

The wsbind file contains information to let CICS create main storage blocks to map data
between XML and language structures. Example 8-4 shows a sample WSBIND job.

Example 8-4 CICS Web Services Assistant, JCL Sample, DFHLS2WS


//MYLS2WS JOB ’accounting information’,name,MSGCLASS=A
// SET QT=’’’’
//JAVAPROG EXEC DFHLS2WS,
// TMPFILE=&QT.&SYSUID.&QT
//INPUT.SYSUT1 DD *
PDSLIB=//CICSHLQ.CICS.SDFHSAMP
REQMEM=DFH0XCP4
RESPMEM=DFH0XCP4
LANG=COBOL
PGMNAME=DFH0XCMN
TRANSACTION=XML1
MAPPING-LEVEL=2.0
URI=exampleApp/inquireSingle
PGMINT=CHANNEL
WSBIND=/u/exampleapp/wsbind/inquireSingle.wsbind
WSDL=/u/exampleapp/wsdl/inquireSingle.wsdl
/*

CICS Web Services supports the following security protocols:


򐂰 SSL/TLS
򐂰 WS-Security
򐂰 WS-Trust
򐂰 Customized Security handler

108 XML Processing Options on z/OS


8.6 CICS Transform statement
With CICS TS 4.1 and later release, you are independent of the communication channel
when parsing XML. As a supplement to CICS WebService, the TRANSFORM statement
(Example 8-5) allows you to parse XML in your application, receiving the XML string from
other channels than HTTP or MQ and without using the SOAP protocol.

Example 8-5 Transform statement, parse XML


EXEC CICS TRANSFORM XMLTODATA
XMLTRANSFORM('MyXmlTransformName')
CHANNEL('MyChannelName')
XMLCONTAINER('SourceContainerName')
DATCONTAINER('TargetContainerName')

Conversion modules are available to prepare for the TRANSFORM statement with the same
tools as used for CICS Web Services. See 8.5.1, “CICS Web Services Assistant” on
page 107.

If your conversion modules is created from an XML schema and not a language structure,
there might be more than one transformation between XML and language structure. To allow
you to control the assignment of the correct language structure, two extra parameters,
ELEMNAME and ELEMNAMELEN, on the TRANSFORM statement inform you of the root
element name. Knowing the root element name, it is possible to assign the correct data
structure to the containers received. See Example 8-6.

Example 8-6 Transform statement, parse XML, with ELEMNAME option


EXEC CICS TRANSFORM XMLTODATA
XMLTRANSFORM('MyXmlTransformName')
CHANNEL('MyChannelName')
XMLCONTAINER('SourceContainerName')
DATCONTAINER('TargetContainerName')
ELEMNAME(elementName) ELEMNAMELEN(elementNameLength)

If your application can receive XML messages that are derived from different XML schemas,
you need to inspect the XML string to determine the relevant conversion. To handle this, first
call the TRANSFORM API, get the element name, and decide from the element name which
XMLTRANFORM is needed to parse the entire string. Then call the TRANSFORM API again
with the relevant XMLTRANSFORM option, as shown in Example 8-7.

Example 8-7 Transform statement, unknown XML schema


EXEC CICS TRANSFORM XMLTODATA
CHANNEL('MyChannelName')
XMLCONTAINER('SourceContainerName')
ELEMNAME(elementName) ELEMNAMELEN(elementNameLength)

EXEC CICS TRANSFORM XMLTODATA


XMLTRANSFORM('MyXmlTransformName')
CHANNEL('MyChannelName')
XMLCONTAINER('SourceContainerName')
DATCONTAINER('TargetContainerName')

Chapter 8. How to parse XML 109


Validation
The default for the TRANSFORM statement is that checking is performed to ensure the
message is well-formed. For testing purposes it is possible to add a control for valid XML. To
enable validation you must:
1. Ensure that the XML binding and the schema are in the same location on z/OS UNIX. The
XMLTRANSFORM resource defines these files to CICS. You can use the INQUIRE
XMLTRANSFORM command to check the location of each file.
2. Turn validation on for the application. Use the CEMT or SPI command SET
XMLTRANSFORM(name) VALIDATION, where name is the XMLTRANSFORM resource.

The result from the validation control is not returned to the application, but only
communicated through log messages. Check the system log to ascertain whether the XML
transformation is valid:
򐂰 Message DFHML0508 indicates that the XML was successfully validated.
򐂰 Message DFHML0507 indicates that the validation failed.

8.7 Parsing with pureXML


DB2 9 for z/OS supports both validating and non-validating parsing of XML. Input XML can be
contained within XML host variables or files referenced by file reference variables. Outside of
an application you can import XML (with or without validation) directly into a table using the
DB2 Command Editor or command line processor. The import function uses DB2 INSERT
statements behind the scenes. DB2 uses z/OS XML System Services for parsing

8.7.1 Simple DB2 parsing without validation


Example 8-8 shows how to parse an XML stream and insert its contents into a table.

Example 8-8 DB2 parse without validation


INSERT INTO table VALUES (col-1-val, col-2-val, XMLPARSE ( DOCUMENT :xml-host
STRIP WHITESPACE))

XMLPARSE will STRIP or PRESERVE whitespace when specified. XMLPARSE will also
accept XML strings from columns and SQL expressions. XMLPARSE only accepts
well-formed XML documents as defined in XML 1.0.

8.7.2 Simple DB2 parsing with validation


For parsing with validation, you must register your XML schemas with DB2. Registering
schemas can be done through graphical wizards from the DB2 Control Center, invoking the
XSR_REGISTER system-supplied stored procedure, or issuing DB2 commands directly.
Example 8-9 on page 111 shows how to register a schema by issuing commands.

110 XML Processing Options on z/OS


Example 8-9 DB2 commands to register an XML schema
REGISTER XMLSCHEMA :xml-schema-name FROM :XSD-file-name-and-path1
WITH :properties-file-name-and-path1 AS :SQL-schema-name
ADD :sub-schema-name FROM :XSD-file-name-and-path2 WITH
:properties-file-name-and-path2
ADD :sub-schema-name FROM :XSD-file-name-and-path3 WITH
:properties-file-name-and-path3
COMPLETE WITH :schema-properties-file-name-and-path4
ENABLE DECOMPOSITION

For additional information, see DB2 Version 9.1 for z/OS Command Reference, SC18-9844.

Sub-schemas are only required when the primary schema document references other
schema documents. The ENABLE DECOMPOSITION subcommand allows the schema to be
referenced by the DECOMPOSE command processor command, which is used to shred
XML.

The registered schema is not tied to one specific table or column. It can be used to validate
any document that complies to the schema. Example 8-10 shows several (of many) variations
for the insert with validation syntax.

Example 8-10 DB2 insert with XML validation


INSERT INTO table (column list) VALUES (col-1-val, col-2-val, XMLPARSE (DOCUMENT
SYSFUN.DSN_XMLVALIDATE(:xml-host, 'SYSXSR.schema')))

INSERT INTO table (column list) VALUES (col-1-val, col-2-val, XMLPARSE (DOCUMENT
SYSFUN.DSN_XMLVALIDATE(:xml-host, 'SYSXSR', :host-schema-name)))

INSERT INTO table (column list) VALUES (col-1-val, col-2-val, XMLPARSE (DOCUMENT
SYSFUN.DSN_XMLVALIDATE( CAST :char-host AS CLOB, :host-sysxsr-schema-name)))

INSERT INTO table (column list) VALUES (col-1-val, col-2-val, XMLPARSE (DOCUMENT
SYSFUN.DSN_XMLVALIDATE( xml-file-reference-variable ,'SYSXSR.schema')))

The IBM Information Management Software for z/OS Solutions Information Center includes
additional examples and the most up-to-date information. The IBM Information Management
Software for z/OS Solutions Information Center can be found at the following Web page:
http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp

For additional information regarding XML parsing within DB2, refer to the following resources:
򐂰 DB2 Version 9.1 for z/OS SQL Reference, SC18-9854
򐂰 DB2 Version 9.1 for z/OS Application Programming and SQL Guide, SC18-9841
򐂰 DB2 9: pureXML Overview and Fast Start, SG24-7298
򐂰 DB2 9 pureXML Guide, SG24-7315

Chapter 8. How to parse XML 111


112 XML Processing Options on z/OS
9

Chapter 9. Hints, tips, and samples


In this chapter we provide examples and advice for compiling, binding, and executing some of
the features available for XML processing on z/OS. We also provide working code samples
and sample output. These can be helpful when developing an application using z/OS XML
System Services.

© Copyright IBM Corp. 2009. All rights reserved. 113


9.1 Validation using optimized schema representation (OSR)

9.1.1 Creating an OSR


When you are using the z/OS XML System Services with validation, you must provide an
Optimized Schema Representation (OSR) to the parsing process. The OSR is created from
the XML schema definitions (XSD files) that define the acceptable XML content. If you need
multiple schemas (XSD files) for the validation, you can collect these into one OSR. To create
the OSR, z/OS XML Systems Services provides a tool called xsdosrg. To create an OSR you
issue the xsdosrg command under a z/OS UNIX shell. A description of xsdosrg can be found
in the XML System Services User’s Guide and Reference, SA23-1350.

There might be requirements to use this tool outside the z/OS UNIX shell, for example, the
XSD/OSR combination is part of a change management system. In this case, it might be
more convenient to run this tool in a pure batch environment. One way is to use the batch
interface routine from z/OS UNIX, BPXBATCH. Another way to address this requirement is to
make xsdosrg an executable that can be loaded from a partitioned data set. This allows
xsdosrg to be within the standard JOBLIB/STEPLIB libraries. Specifically, the output can be
easily put into archiving tools. We discuss the necessary steps to achieve this.
1. Copy over the xsdosrg tool to a partitioned data set extended (PDSE). This can be done
from the z/OS UNIX shell using the following copy command.
(cp):
cp /bin/xsdosrg "//'HDM.SG7810.LOADE(XSDOSRG)'"
After that we have an executable version of xsdosrg in the PDSE. In our example it is
HDM.SG7810.LOADE.

Note: You need to keep track of the service level of xsdorsg to avoid running an
outdated version. Alternatively, you can copy the xsdosrg program to a temporary
PDSE before executing it. Executable modules can be copied using the program
management binder, IKJEFT01 TSO command processor, or BPXBATCH UNIX batch
command processor. Example 9-1 shows use of the program management binder to
copy the xsdosrg executable before executing it.

The next step is to create the JCL to execute xsdosrg in batch. Example 9-1 shows the job
we used in our project.

Example 9-1 Example JCL to run xsdosrg in batch


//XSD2OSR JOB (999,POK),NOTIFY=HDM,
// CLASS=A,MSGCLASS=T,MSGLEVEL=(1,1)
/*JOBPARM SYSAFF=SC80 <<<<<<<<<<<<<<<<<<< !!!
// SET L='/u/hdm/sg7810/xsd.lst'
//** Use program binder to copy the current version of the xsdosrg program
//COPYEXEC EXEC PGM=IEWBLINK, PARM='LIST,MAP,CASE=MIXED'
//SYSLMOD DD DSN=HDM.SG7810.LOADE(XSDOSRG),DISP=SHR
//SYSOBJ DD PATH='//bin/xsdosrg',PATHDISP=(KEEP,KEEP)
//SYSLIN DD *
INCLUDE SYSOBJ(XSDOSRG)
ENTRY XSDOSRG
NAME XSDOSRG(R)
/*
//**
//** Execute xsdosorg to translate schemas to OSR

114 XML Processing Options on z/OS


//DOIT EXEC PGM=XSDOSRG,REGION=0M,
// PARM='/ -v -o /u/hdm/sg7810/test.osr -l &L'
//STEPLIB DD DISP=SHR,DSN=HDM.MAIN.PDSE
//ENV DD PATH='/u/hdm/sg7810/xsd2osr.env',PATHOPTS=(ORDONLY),
// PATHDISP=(KEEP,KEEP)
//CEEOPTS DD *
ENVAR("_CEE_ENVFILE=DD:ENV"),
RPTOPTS(ON),RPTSTG(ON),POSIX(ON),
ANYHEAP(4M,128K,ANYWHERE,FREE),
HEAP(92M,256K,ANYWHERE,KEEP,8192,4096)
//STDERR DD SYSOUT=*
//STDOUT DD SYSOUT=*

The slash after the PARM= separates those options that are specific to Language
Environment from those which are passed to the program, here xsdosrg. With the -v we
asked for details of the run, the -o test.osr identifies the output file, and with the -l &L
we pass the name of a list file to xsdosrg.
The more important settings here are those which help to establish the necessary
environment for xsdosrg to run. These are directed by the DD name of CEEOPTS to
Language Environment. The important settings are the reference to the file with the
environment variable settings (ENVAR) and the POSIX(ON) setting.
The settings to establish the environment are shown Example 9-2. These are the LIBPATH
and the CLASSPATH environment variables we used. These options are stored in the
/u/hdm/sg7810/xsd2osr.env file. The necessary definitions can be found in the XML
System Services User’s Guide and Reference, SA23-1350.

Example 9-2 Example of environment settings


_BPX_BATCH_UMASK=0022
_BPX_BATCH_SPAWN=YES
_BPX_SHAREAS=YES
LIBPATH=/usr/lib:/usr/lpp/java/J5.0/bin:/usr/lpp/java/J5.0/bin/j9vm:/usr/lib/ja
va_runtime/
CLASSPATH=/usr/include/java_classes:

Your working environment on z/OS UNIX might also need these path settings. A good
place to set the definitions is the .profile script.
2. When this batch job is started, a z/OS UNIX environment is created based on various
sources. One is the OMVS segment that is assigned to the user ID under which the job
runs. In our case this is HDM. When the job starts it will be positioned with a current
working directory of /u/hdm. As we have stored our XSD files in the directory
/u/hdm/sg7810 we need to define the source directory of the XSD files also. Otherwise it
would be assumed to be in HDM’s home directory. Example 9-3 shows the content of our
file xsd.lst.

Example 9-3 Schema, list of xsd files


********************************* Top of Data ***********
/u/hdm/sg7810/S2SDDpacs.002.001.02.xsd
/u/hdm/sg7810/S2SDDpacs.003.001.01.xsd
/u/hdm/sg7810/S2SDDpacs.006.001.01.xsd
******************************** Bottom of Data *********

Chapter 9. Hints, tips, and samples 115


Now that everything is set up we can run the generator. Example 9-4 shows the output
that is created during the generation.

Example 9-4 Output from the OSRGEN tool in batch


SDSF OUTPUT DISPLAY XSD2OSR JOB06817 DSID 104 LINE 0
COMMAND INPUT ===>
********************************* TOP OF DATA *************
OSR file: /u/hdm/sg7810/test.osr
Number of schemas: 3
Schema file: /u/hdm/sg7810/S2SDDpacs.002.001.02.xsd
Schema file: /u/hdm/sg7810/S2SDDpacs.003.001.01.xsd
Schema file: /u/hdm/sg7810/S2SDDpacs.006.001.01.xsd
Ý--- Calling gxluInitOSRG ---¨
Ý--- Calling gxluLoadSchema ---¨ #1
Ý--- Calling gxluLoadSchema ---¨ #2
Ý--- Calling gxluLoadSchema ---¨ #3
Ý--- Calling gxluGenOSR ---¨
Writing the OSR to: /u/hdm/sg7810/test.osr
Ý--- Calling gxluControlOSRG ---¨
Ý--- Calling gxluTermOSRG ---¨
******************************** BOTTOM OF DATA ***********

3. As a final check, look at the directory /u/hdm/sg7810 to see that the OSR has been stored
correctly. See Example 9-5.

Example 9-5 Directory listing to check the generated OSR


HDM § SC80:/u/hdm::>cd sg7810
HDM § SC80:/u/hdm/sg7810::>ls -al
total 600
drwxr-xr-x 2 HDM SYS1 704 Aug 5 18:01 .
drwxr-xr-x 3 HDM SYS1 384 Aug 5 15:55 ..
-rw-r----- 1 HDM SYS1 34382 Aug 4 22:02 S2SDDpacs.002.001.02.xsd
-rw-r----- 1 HDM SYS1 35206 Aug 4 22:02 S2SDDpacs.003.001.01.xsd
-rw-r----- 1 HDM SYS1 32510 Aug 4 22:02 S2SDDpacs.006.001.01.xsd
-rw-r--r-- 1 HDM SYS1 174027 Aug 5 17:57 test.osr
-rw-r----- 1 HDM SYS1 117 Aug 5 15:55 xsd.lst
-rw-r----- 1 HDM SYS1 188 Aug 4 22:55 xsd2osr.env
HDM § SC80:/u/hdm/sg7810::>

9.1.2 Parse with validation: Using the OSR


Parsing with validation requires a service routine to be brought into storage before the actual
parse starts. This is done by a call to GXL1LOD, which allows the loading of a z/OS function.
The only one currently available is the validating parser. This is indicated to the load function
through the first parameter (function_code).

Example 9-6 on page 117 shows the necessary calls in an assembler program to do a
validating parse using the XML System Services. In this extract, we do not show the read
routines to do a get of the OSR and the XML string into storage. You see that there is only a
small difference between a simple parse and a validating parse.

116 XML Processing Options on z/OS


Example 9-6 Sequence of call to XML System Services to do a validated parse
- - - - - - - - - - - - - - - - 92 Line(s) not Displayed
CALL GXL1LOD,(FCCODE,ZERO,RCD,RSN),MF=(E,PARMAREA)
- - - - - - - - - - - - - - - - 78 Line(s) not Displayed
CALL GXL1INI,(PIMA,PIMALEN,CCSID,FEAT,ZERO,ZERO,RCD,RSN), +
- - - - - - - - - - - - - - - - 20 Line(s) not Displayed
CALL GXL1CTL,(PIMA,CTLOP,CTLD,RCD,RSN),MF=(E,PARMAREA)
- - - - - - - - - - - - - - - - 27 Line(s) not Displayed
CALL GXL1PRS,(PIMA,ZERO,PIN,LIN,OUTBUFP,OUTBUF#,RCD,RSN), +
- - - - - - - - - - - - - - - - 19 Line(s) not Displayed
CALL GXL1TRM,(PIMA,RCD,RSN),MF=(E,PARMAREA)
- - - - - - - - - - - - - - - 327 Line(s) not Displayed

In a COBOL or PL/I program, the sequence would be the same if using the XML System
Services parser through APIs.

For an example of a validating parse in COBOL using the XML PARSE statement, see
Enterprise COBOL for z/OS Version 4.2 Programming Guide, SC23-8529.

9.1.3 Basic flow of a program to handle parsed data


In Example 9-7 we extracted the basic steps needed to walk through the buffer that is
returned by the z/OS XML System Services parser. For easy reading we highlighted the
control codes identifying a tag or comment. As we took the code directly from our PL/I
example, we have excluded the print statements.

Example 9-7 Program flow for navigating XML parsed data stream
current_record = buffer_addr;
do while( current_record < buffer_current_addr );

bufptr = current_record;

- - - - - - - - - - - - - - - - 6 Line(s) not Displayed


select( bufptr->gxl_rectyp );
when( gxl_rt_buffer_info )
do;
- - - - - - - - - - - - - - - - 2 Line(s) not Displayed
end;
when( gxl_rt_xml_decl )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
- - - - - - - - - - - - - - - - 2 Line(s) not Displayed
lvaddr += stg(gxl_vallen) + lvaddr->gxl_vallen;
- - - - - - - - - - - - - - - - 2 Line(s) not Displayed
lvaddr += stg(gxl_vallen) + lvaddr->gxl_vallen;
- - - - - - - - - - - - - - - - 2 Line(s) not Displayed
end;
when( gxl_rt_start_elem )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
- - - - - - - - - - - - - - - - 2 Line(s) not Displayed
end;
when( gxl_rt_end_elem )
;

Chapter 9. Hints, tips, and samples 117


when( gxl_rt_attr_name )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
- - - - - - - - - - - - - - - - 2 Line(s) not Displayed
end;
when( gxl_rt_attr_value )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
- - - - - - - - - - - - - - - - 2 Line(s) not Displayed
end;
when( gxl_rt_ns_decl )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
- - - - - - - - - - - - - - - - 2 Line(s) not Displayed
end;
when( gxl_rt_char_data )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
- - - - - - - - - - - - - - - - 2 Line(s) not Displayed
end;
when( gxl_rt_start_cdata )
do;
;
end;
when( gxl_rt_end_cdata )
do;
;
end;
when( gxl_rt_whitespace )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
- - - - - - - - - - - - - - - - 2 Line(s) not Displayed
end;
when( gxl_rt_pi )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
- - - - - - - - - - - - - - - - 2 Line(s) not Displayed
lvaddr += stg(gxl_vallen) + lvaddr->gxl_vallen;
- - - - - - - - - - - - - - - - 2 Line(s) not Displayed
end;
when( gxl_rt_comment )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
- - - - - - - - - - - - - - - - 2 Line(s) not Displayed
end;
when( gxl_rt_dtd_data )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
- - - - - - - - - - - - - - - - 2 Line(s) not Displayed
end;
when( gxl_rt_unresolved_ref )
;
when( gxl_rt_error )
do;
- - - - - - - - - - - - - - - - 4 Line(s) not Displayed

118 XML Processing Options on z/OS


end;
end;

current_record += bufptr->gxl_reclen;
end;

With the selections you get a first frame for your program using the z/OS XML System
Services parser.

For a complete listing of the PL/I program, see Example B-2 on page 167.

9.1.4 Basic loop to manage the input and output buffer


The next major part of a program that uses z/OS XML System Services is the management of
the input butter. The important reason codes your program has to look for after the parse are
x’1301’, x’1303’, and x’1304’. These will indicate the status with the buffer. The return code
from the parser is 4, which also has to be looked for.

From the z/OS Users Guide and Reference we get the following explanations.
򐂰 1301, XRSN_BUFFER_INBUF_END, The end of the input buffer has been reached.
򐂰 1303, XRSN_BUFFER_OUTBUF_END The end of the output buffer has been reached
򐂰 1304, XRSN_BUFFER_INOUTBUF_END The end of both buffers have been reached.

Example 9-8 shows how we have handled these three reason codes. The excerpt is taken
from the full example shown in Example B-2 on page 167. The only place where new input is
provided to the input buffer is with the read in the line marked 1.

For the most part, this excerpt corresponds to the flow chart in Figure 6-3 on page 72.

Example 9-8 Error checking for navigating XML parsed data stream
if return_code = 4 then
select( reason_code );
when( gxl_rsn_buffer_inbuf_end
,gxl_rsn_buffer_inoutbuf_end )
do; /* 1301, 1304 */
call read_xml( xmldocument ); 1

/* reset doc fields for further parse */


document_addr = addrdata(xmldocument);
document_len = length(xmldocument);

/* copy doc addr to mutable field */


document_current_addr = document_addr;

/* copy doc length to mutable field */


document_len_remaining = document_len;
if reason_code = '1301'xn then c_1301=c_1301+1 ; else
c_1304 = c_1304 + 1;
end;
when( gxl_rsn_buffer_outbuf_end ) do;
c_1303 = c_1303 + 1;
end ; /* 1303 */
otherwise
leave;

Chapter 9. Hints, tips, and samples 119


end;
else
leave;
end;

rc = gxl1trm( pima_addr,
return_code, reason_code );

/* print out some statistics */


put skip edit ( 'size; reads; readed;') (a) ;
put edit ( 'c_1301; c_1303; c_1304;') (a);
put skip edit ( size, ';', reads, ';', readed,';')
( f(8), a, f(8), a, f(8), a ) ;
put edit (c_1301,';', c_1303,';', c_1304, ';')
( f(8), a, f(8), a, f(8), a ) ;
end;

We also counted in our small program the number of occurrences of each of these reason
codes. This might also be helpful in your environment as it provides an indication how well the
sizes of the input and output buffer are selected. The relation of these are dependent on the
individual XML document processed, so there is no fundamental rule available how to size
them. A good starting point is 4 kB for the input buffer, and 8 kB for the output buffer.

9.1.5 Detailed view at the parsed data stream


To give an indication of how the buffer returned by the parser looks, we show a small sample
in Example 9-9. It shows the simple XML string given to the parser.

Example 9-9 Simple XML string to be parsed


<?xml version="1.0" standalone="yes" ?>
<racfunload>
<user>
<name>
<first>Hans</first>
<last>Mertiens</last>
</name>
<tso>
<userid>HDM</userid>
<group>SYS1</group>
</tso>
<omvs>
<uid>58</uid>
<gid>1</gid>
<home>/u/hdm</home>
<bpx>
<superuser>allowed</superuser>
</bpx>
</omvs>
</user>
</racfunload>

The XML string is coded with codepage IBM-037. We pass this information as a parameter to
the parser. The buffer returned by the parser is shown in Example 9-10 on page 121.

120 XML Processing Options on z/OS


Beginning at 1 we show basic information about the buffer, such as length, and the basic
information from the XML string.

At 2 we start with the listing of the elements contained in our string. Each starts with the
indicator of _START_ELEM. As we have several consecutive elements nested
(<racfunload><user><name><first> we find the first returned data at 3. Which belongs to the
last tag started which is <first> in our case.

Example 9-10 Buffer retuned by the parser with simple decoding


GXL_RT_BUFFER_INFO 1
0000000000000288 0000000000000000
GXL_RT_XML_DECL
3 1.0
0
3 yes
GXL_RT_START_ELEM 10 racfunload 2
GXL_RT_START_ELEM 4 user
GXL_RT_START_ELEM 4 name
GXL_RT_START_ELEM 5 first
GXL_RT_CHAR_DATA 4 Hans 3
GXL_RT_END_ELEM
GXL_RT_START_ELEM 4 last
GXL_RT_CHAR_DATA 8 Mertiens
GXL_RT_END_ELEM
GXL_RT_END_ELEM
GXL_RT_START_ELEM 3 tso
GXL_RT_START_ELEM 6 userid
GXL_RT_CHAR_DATA 3 HDM
GXL_RT_END_ELEM
GXL_RT_START_ELEM 5 group
GXL_RT_CHAR_DATA 4 SYS1
GXL_RT_END_ELEM
GXL_RT_END_ELEM
GXL_RT_START_ELEM 4 omvs
GXL_RT_START_ELEM 3 uid
GXL_RT_CHAR_DATA 2 58
GXL_RT_END_ELEM
GXL_RT_START_ELEM 3 gid
GXL_RT_CHAR_DATA 1 1
GXL_RT_END_ELEM
GXL_RT_START_ELEM 4 home
GXL_RT_CHAR_DATA 6 /u/hdm
GXL_RT_START_ELEM 3 bpx
GXL_RT_START_ELEM 9 superuser
GXL_RT_CHAR_DATA 7 allowed
GXL_RT_END_ELEM
GXL_RT_END_ELEM
GXL_RT_END_ELEM
GXL_RT_END_ELEM
GXL_RT_END_ELEM

It is the responsibility of your application to navigate through these records and move the
values into the right variable.

Chapter 9. Hints, tips, and samples 121


9.1.6 Get a StringID exit working
This section discusses some details you might find helpful in developing a StringIDHandler
exit routine.

Handling a C Program and its Bare Metal C clone


The StringIDTable contains of a combination of a string and an associated StringID. This table
is generated automatically during the generation of the OSR with the xsdosrg command or
with your own OSR generator. If you do not provide an exit the parser presents the string itself
as the StringID. Controlling the StringIDTable with a special exit has several advantages.
Amont others, you have a binary number that identifies a string. Besides a better use of the
output buffer, it is usually easier to control the assignment of a function to a StringID based on
a number. As there is currently no way to provide this exit to the generator provided by XML
System Services, you need to write your own tool to create the OSR. In this tool you can then
provide your own StringIDHandler to the generator gxluGenOSR. You might already be doing
this for other reasons. For example, the schema’s XSD file to be converted is stored in a
VSAM file, which the xsdosrg tool cannot handle.

Note: The StringIDHandler exit has to be written in C or Assembler.

When you parse the XML document you might provide a StringIDTable exit. It is suggested to
use the same exit which you provided when the OSR was generated. This suggestion is
mainly due to the fact that the exits are then based on the same source. Further, you have
control over the assignment of a number (function) to a string, even across multiple schemas
(XSD files).

The parser does not provide an environment to run a program which uses Language
Environment services. This is usually the case with all C, C++, PL/I, or Cobol code on z/OS.
One solution to have a program without Language Environment services is to use Assembler.
Another way to achieve this is to use the Metal C version of a C program. The Metal C
(-qmetal) option has been provided with the XLC Compiler since z/OS V1R9. The compiler
generates code that does not have Language Environment run-time dependencies. So, with
one source written in C, it is possible to support both instances: the generation of the OSR
and the parsing.

The XLC C compiler also provides means to add Assembler instructions within the C code.
These instructions conform with the different linkage conventions at the time the parse takes
place. The linkage statements are placed between prolog and epilog statements, as shown
in Example 9-11 on page 124. Based on this it should be easy to create these two exits based
on the same source code. If necessary you can add more code in Assembler, but this is the
basic requirement.

The process to handle both types of sources is shown in Figure 9-1 on page 123. For our
purposes we copied the StringIDHandler exit example provided in
SYS1.SAMPLIB(GXLESTRI) into our z/OS UNIX environment. We renamed it to StrIDx.c On
the left side of Figure 9-1 on page 123 the C code is compiled the usual way with the C
compiler. We do it from the z/OS UNIX command line. Also from a z/OS UNIX shell we
executed a XLC command that generates a ‘bare metal C’ version of our StringID handler
exit. This happens on the right side of Figure 9-1 on page 123.

The process might also be executed in a batch environment using usual jobs.

122 XML Processing Options on z/OS


Process to build C and its Metal C companion for

C source
StrIDx.c

xlc -WC,nosearch -S -qmetal –I


xlc –c StrIDx.c
/usr/include/metal/ StrIDx.c (*)

Make a dll xlc -c StrIDx.s

* Note: for display purposes only the xlc command is split across lines
Figure 9-1 Creating a string ID handler exit routine

Note:
򐂰 You need to use the XLC compiler interface. Otherwise you cannot get bare Metal C
output. In addition, with the c89 command you will get an error near line 300.
򐂰 It absolutely necessary to force XLC to include the header for the Metal C conversion
from /usr/include/metal.

We then copied the Assembler version of it (stridx.s) into a partitioned data set for the
following steps.

Note: As the source code is contained in SYS1.SAMPLIB(GXLESTRI) we did not copy it


here or in the appendix. Only relevant pieces are shown here.

When this StringIDHandler exit routine is being used as an exit to the XML System Services
parser:
򐂰 A prolog and an epilog are required. This is required to take care of the different linkage
conventions at parse time. Also needed in this example is the setup of a Dynamic Stack
Area (DSA). More details are below.
򐂰 In the workarea, and immediately following the DSA/Stack space, is the storage that will
be mapped to the string ID table (XSI) as the exit structures it.

The DSA is used because this exit uses local variables. It would also be necessary if you
need to use other services from the C runtime library. For a complete list of services that
might be used in a bare metal C environment, see the z/OS Metal C Programming Guide and
Reference, SA23-2225.

Chapter 9. Hints, tips, and samples 123


This area is passed to the initialization routine of the parser (GXLINI) through the system
service parameter area. For a graphical representation of this see Figure 9-2.

GXLESTRI StringIDHandler Exit System Services Parameter area

2kB of memory used as DSA space


(mainly for calls to C services)

Memory to hold StringID table

Area is provided by the application in System Services Parameter Area


Figure 9-2 System services parameter area for the GXLESTRI StringIDHandler exit

At first we show the necessary elements that have to be added to the C program to make it
usable in both environments. As the housekeeping (or the linkage conventions) are different
from those established by the C compiler, we need to add the necessary assembler
instructions. Example 9-11 shows this detail.

Example 9-11 Prolog for a METAL C program


#ifdef __IBM_METAL__

#ifdef _LP64 /* If AMODE 64... */ 1


#pragma.prolog(STRIEXIT," STMG 14,12,12(13)\n \
LG 15,0(1)\n \
LG 15,0(15)\n \
STG 15,8(,13)\n \
STG 13,4(,15)\n \
LGR 13,15")
#pragma.epilog(STRIEXIT, " LG 13,4(13)\n LMG 14,12,12(13)\n BR 14") 2
#else /* Else we are AMODE 31 */ 1
#pragma.prolog(STRIEXIT," STM 14,12,12(13)\n \
L 15,0(1)\n \
L 15,0(15)\n \
ST 15,8(,13)\n \
ST 13,4(,15)\n \
LR 13,15")
#pragma.epilog(STRIEXIT, " L 13,4(13)\n LM 14,12,12(13)\n BR 14") 2
#endif /* End AMODE check */

124 XML Processing Options on z/OS


At 1 the generation of code continues according to the selected addressing mode, _LP64 is
equivalent to AMODE 64. Otherwise it will run in AMODE 31. The following instructions
establish the housekeeping with the caller. A similar piece is provided as an epilog to manage
the return to the parser (2).

Here we show how to establish addressability of the small DSA we need. It is conditionally
implemented using the define __IBM_METAL__ 1. See Example 9-12. For the Metal C
environment the code following is included, otherwise just the XSI is addressed from the
system services parameter area.

Example 9-12 Conditional include for DSA handling in bare Metal C


#ifdef __IBM_METAL__ 1
ptr_val = (unsigned long long)(*sys_svc_parm);
ptr_val += XSI_DSA_SPACE;
xsi = (XSI*)(ptr_val) ;
xsi->storage_space -= XSI_DSA_SPACE;
#else
xsi = (XSI*)(*sys_svc_parm);
#endif

Note: The system services parameter is used as work area for the StringIDHandler exit.

For more information about the use of Metal C, see z/OS Metal C Programming Guide and
Reference, SA23-2225.

How to populate the System Service Vector


Another piece of information needed for XML System Services is the vector that contains
addresses to special services provided by the user. There are three exits routines you might
provide to the XML System Services through the system services vector. These are the
storage routines (get and free storage respectively) and the StringIDHandler exit. See
Figure 9-3 on page 126. The vector is made of two parts, a counter followed by three
addresses. If you provide a storage allocation exit, you also need to provide a peer
deallocation exit.

Chapter 9. Hints, tips, and samples 125


XML System Services Vector Layout

Counter

Storage Allocation or NULL

Storage Deallocation or NULL

StringIDHandler

Counter is always 4 bytes long, it is null when no exit is defined,


or three if any is defined
The storage routines always have be defined in pairs.
Addresses are 4 bytes long for AMODE31 (LP32)
Addresses are 8 bytes long for AMODE64 (LP64)
Figure 9-3 System Services Vector passed to XML System Services

In our PL/I example we used the fetch 1 built-in function to load the service from steplib and
to get the entry point address at the same time. The StringIDHandler exit is contained in load
module STRIDX. See Example 9-13.

Example 9-13 How to fill the system services vector


dcl 1 xsv aligned ,
2 xsv_count fixed bin (31) init(0) ,
2 xsv_entries (3) pointer ;
dcl xsv_p pointer ;
dcl idi_p pointer ; /* pointer to be used with fetch() */
dcl stridx entry ;
fetch STRIDX set (idi_p) ; 1

xsv_p = addrdata (xsv) ;


xsv.xsv_count = 3 ;
xsv.xsv_entries(3) = idi_p ;

The address of this vector is passed to the initialization routine gxlpinit(), GXL1INI, or
GXL4INI depending on the language or addressing mode you use. See Example 9-14.

Example 9-14 Passing system services parameter to the x/OS XML parser
rc = gxl1ini( pima_addr, pima_len,
ccsid, features,
/* sysnull(), sysnull(), */
xsv_p, addrdata(xsi_p) ,
return_code, reason_code );

Note: When you create a separate load module for your exit, such as to fetch this from a
library, you need to provide the correct entry point.

126 XML Processing Options on z/OS


How to populate the system services parameter area
Depending on the requirements of the StringIDHandler exit, you have to provide:
򐂰 Space for a DSA. Your exit will use local variables such as int i; .

Note: An exit written in Assembler does not need a DSA. But in case it needs work
space, you can do it the same way as described here. This would keep your exit free of
further storage handling.

򐂰 Space for the work area. If you have prepared a StringIDTable when the OSR was
generated you should provide the data from that table to the exit. Remember to take care
of location dependent data. In case you have not generated a StringIDTable earlier, the
exit always will create a fresh one.

Example 9-15 shows a PL/I structure to provide these areas

Example 9-15 XML System Services parameter for GXLE1IDI


/* System Services Parameter (area) */
/* the declares for the string ID exit */

dcl 1 xsi aligned ,


2 xsi_dsa(256) fixed bin (63),/* Space for DSA */
2 xsi_eye char(4) ,/* space for eye catcher */
2 xsi_version fixed bin(31), /* a version indication */
2 xsi_stg_space fixed bin(31) ,
2 xsi_diag_code fixed bin(31) ,
2 xsi_next_id fixed bin(31) init(1) ,
2 xsi_index fixed bin(31) , /* set by exit */
2 xsi_wrk (10240) fixed bin (31) /* Space for work*/ ;

dcl xsi_p pointer ;


xsi_p = addrdata (xsi.xsi_eye) ;
xsi.xsi_stg_space = stg (xsi.xsi_wrk) ;
xsi.xsi_version = 7 ;

With these preparations we were able to get this StringIDHandler exit working. Example 9-16
shows the output for the same XML document we used in Example 9-10 on page 121.

Example 9-16 Output buffer with string IDs from GXLESTRI


GXL_RT_XML_DECL
3 1.0
0
3 yes
GXL_RT_START_ELEM 6 00000006
GXL_RT_START_ELEM 7 00000007
GXL_RT_START_ELEM 8 00000008
GXL_RT_START_ELEM 9 00000009
GXL_RT_CHAR_DATA 4 Hans
GXL_RT_END_ELEM
GXL_RT_START_ELEM 10 0000000A
GXL_RT_CHAR_DATA 8 Mertiens
GXL_RT_END_ELEM
GXL_RT_END_ELEM
GXL_RT_START_ELEM 11 0000000B

Chapter 9. Hints, tips, and samples 127


GXL_RT_START_ELEM 12 0000000C
GXL_RT_CHAR_DATA 3 HDM
GXL_RT_END_ELEM
GXL_RT_START_ELEM 13 0000000D
GXL_RT_CHAR_DATA 4 SYS1
GXL_RT_END_ELEM
GXL_RT_END_ELEM
GXL_RT_START_ELEM 14 0000000E
GXL_RT_START_ELEM 15 1 0000000F
GXL_RT_CHAR_DATA 2 58
GXL_RT_END_ELEM

With this StringIDHandler exit running, the output buffer from the parser now contains a
number instead of the name of the element. According to the list in Example 9-17 the string
ID 15 (1) is returned for the element name of uid.

Example 9-17 StringID to string conversion with GXLESTRI


StrID#StrLng <String
1 3 <xml
2 36 <http://www.w3.org/XML/1998/namespace
3 5 <xmlns
4 29 <http://www.w3.org/2000/xmlns/
5 5 <space
6 10 <racfunload
7 4 <user
8 4 <name
9 5 <first
10 4 <last
11 3 <tso
12 6 <userid
13 5 <group
14 4 <omvs
15 3 <uid 1
16 3 <gid
17 4 <home
18 3 <bpx
19 9 <superuser

Assembler Exit GXL1IDI


In a further step we selected GXL1IDI as another example for a StringIDHandler exit. It is also
distributed in SYS1.SAMPLIB. We did this exercise because this example shows a more
powerful search and insert strategy than the previous example does with its linear table for
insert and search. For many and long strings to be handled, it might be important to look for
the performance of the StringIDHandler exit (6.1.6, “Concept of StringID” on page 75). For
our purpose we renamed it to GXLEIDI so that the length of the name would not conflict with
the PL/I requirements.

The system service vector is set up as described in “How to populate the System Service
Vector” on page 125.

As this exit builds up a tree structure more data areas are needed. Unfortunately, the example
does not apply the necessary structure by itself. It must be provided by the application. As in
the previous example, this area is then passed as the system services parameter.

128 XML Processing Options on z/OS


Figure 9-4 shows the layout needed by the exit.

GXLE1IDI System Services Parameter Area

Header information

ID list area

Dynamic Area

Free Area

Application needs to provide important header information


The grey shaded area contains data relevant to the exit
The green shaded area holds the string ID table
Figure 9-4 System services parameter area for the GXLE1IDI StringIDHandler exit

In Example 9-18 we show the implementation using a PL/ I structure. The data area needs to
be allocated on a full word boundary. At 0 we set some constants:
򐂰 Maximum symbol size
򐂰 Initial string ID number
򐂰 Maximum IDs expected

In Example 9-18, total space, and free space 1 are set to the size of this structure. The
necessary pointers are stored as shown at 2.

Example 9-18 PL/I structure used as system services parameter for GXLE1IDI
dcl 1 xsi aligned ,
2 xsi_eye fixed bin (63) /* just 8 bytes 4 the eye */
/* will be set to XSIEYECA*/
init(1) , /* 00 */
/* 00 */
2 xsi_sym_max_size fixed bin (31) init(64) , 0 /* 08 */
2 xsi_diag_code fixed bin (31) , /* 0C */
2 xsi_next_id fixed bin (31) init(1) , 0 /* 10 */
2 xsi_max_id fixed bin (31) init(500) , 0 /* 14 */
2 xsi_total_size fixed bin (31) 1 , /* 18 */
2 xsi_free_space fixed bin (31) 1 , /* 1C */
2 xsi_curr_null fixed bin (31) init(0) , /* 20 */
2 xsi_curr_free pointer , /* 24 */
2 xsi_tree_null fixed bin (31) init(0) , /* 28 */
2 xsi_tree_head fixed bin (31) INIT(0) , /* 2C */
2 xsi_dyn_null fixed bin (31) init(0) , /* 30 */
2 xsi_dyn_area31 pointer 2 , /* 34 */
2 xsi_list_null fixed bin(31) ,
2 xsi_list_ptr pointer 2 ,
2 xsi_id_list (16*1024) fixed bin (31) , /* 00 */
2 xsi_dyn_area(16*1024) fixed bin (31) , /* 00 */

Chapter 9. Hints, tips, and samples 129


2 xsi_free_area (8*1024) fixed bin (31) ; 2 /* 00 */

dcl xsi_vp pointer ; /* varying addresses in the XSI */


dcl xsi_p pointer ;
xsi_p = addrdata (xsi) ;
xsi.xsi_free_space = stg(xsi.xsi_free_area ) ; 1
xsi.xsi_total_size = stg(xsi); 1 /* always from scratch */
xsi.xsi_list_ptr = addrdata(xsi.xsi_id_list(1)) ; 2
xsi.xsi_dyn_area31 = addrdata(xsi.xsi_dyn_area(1)); 2
xsi.xsi_curr_free = addrdata(xsi.xsi_free_area (1)); 2

We provided the entry address of our exit through a fetch instruction as we did in the previous
example.

Running our little parser application with this exit gives the same output as with the previous
example. We show a small excerpt from our output listing in Example 9-19. At 1 the element
first is returned as an identifier with a value of 9.

Example 9-19 Output from a parser using GXLE1IDI


GXL_RT_START_ELEM 6 00000006 00000000
GXL_RT_START_ELEM 7 00000007 00000000
GXL_RT_START_ELEM 8 00000008 00000000
GXL_RT_START_ELEM 9 1 00000009 00000000
GXL_RT_CHAR_DATA 4 Hans
GXL_RT_END_ELEM

1 3 ***xml
2 36 ***http://www.w3.org/XML/1998/namespace
3 5 ***xmlns
4 29 ***http://www.w3.org/2000/xmlns/
5 5 ***space
6 10 ***racfunload
7 4 ***user
8 4 ***name
9 5 ***first 1
10 4 ***last
11 3 ***tso

Note: Because it is a good idea to use the same exit at the time when the OSR is
generated and when the parse takes place, we need to point out that this example does
not provide an easy means to save the table and reload it at parse time. This is due to the
fact that much of the control information kept in the system services parameter area is not
relocatable. Nevertheless, the example provides for an efficient search and insert strategy.

9.1.7 Extracting a StringID Table


We have developed a small program with which the StringID table can be extracted from an
OSR. We used the OSR generated in our example in 9.1.1, “Creating an OSR” on page 114.
The complete listing of this program is presented in C program to extract the StringIDTable.

130 XML Processing Options on z/OS


An extract from its output is shown in Example 9-20.
򐂰 The gxluStrIDTable service has returned successfully.
򐂰 Table length is ‘3D8A’ = 15754 bytes.
򐂰 The strIDTable is loaded at 19f7e03c.
򐂰 The table contains ‘18F’x = 399 entries.
򐂰 The string that contains all names starts at ‘2588’x bytes after the beginning of the table.
Strings in the string buffer here are contiguous without the a trailing zero that is usual in C
environments.
򐂰 We display several StringID / name combinations here. For example, the string xmlns has
a length of 5, starts at offset 0 of the string buffer, and is represented by a StringID of 0.
With the other two entries shown you see the offset increasing.

Example 9-20 StringIDTable listing


sizeof(GXLHXSTR) 40, sizeof(GXLHXSTR_TBLENTRY) 24
Number of characters read = 174027

gxluStrIDtable returns with

rc=00000000 rsn=000000001

strIDTbl_l =00003d8a2

strIDTbl_p at 19f7e03c3

XSTR_TBL_NUMSTR 0000018f4

XSTR_TBL_STRBUFFOFFSET 000025885

stepp at 19F7E04C 6
XSTR_TBLENTRY_STRID 00000001 _STRLEN 00000005 _OFFSET 00000000
string xmlns

stepp at 19F7E064 6
XSTR_TBLENTRY_STRID 00000002 _STRLEN 00000003 _OFFSET 00000006
string xml

stepp at 19F7E07C 6
XSTR_TBLENTRY_STRID 00000003 _STRLEN 0000001D _OFFSET 0000000A

9.2 Using the language bindings


z/OS XML System Services provides two sets of interface, one conforming to an Assembler
style of programming, the other set provides for C or C++ type interfaces. Some of the
functions provided with the C/C++ set are not available in the Assembler set.

Both kinds of interface routines provides for 64 bit support.That is, if your program can run in
an 64-bit environment or is designed to run with 64-bit addressing the functions provided
byXML System Services can be used. Currently this is only possible from C/C++ programs, or
with Assembler programs.

Chapter 9. Hints, tips, and samples 131


9.2.1 Assembler interfaces
Actually this class of services should be qualified according to how the parameters are
exchanged between the caller and the callee. This exchange follows the Standard OS
Linkage conventions. (see z/OS MVS Programming: Assembler Services Guide, SA22-7605).
You do not need to write an Assembler program to use these services. What is needed is to
define the entry to a service in a way that the compiler sets up everything (for example,
parameter lists) so the called services find everything according to these linkage conventions.
This can be achieved from COBOL, or PL/I, or even REXX can be directed to call a service
conforming to the convention mentioned above.

The services routines are an intrinsic part of z/OS. As many other services these are loaded
at IPL time and can be addressed through the Communication Vector Table (CVT). You can
address each of these routines with quite simple declarations.

Example 9-21 shows how to call the XML System Services from a PL/I program.

Example 9-21 Call gxlini from a PL/I program going through the CVT
dcl cvt pointer based( ptrvalue(16) );
dcl cvtcsrt pointer based( ptradd(cvt,544) );
dcl csrt(19) pointer based( cvtcsrt );
dcl
gxl1ini entry(
pointer byvalue, /* parse instance memory area (pima) */
fixed bin(31) byaddr, /* pima length */
fixed bin(31) byaddr, /* ccsid of document */
fixed bin(31) byaddr, /* parse feature flags*/
pointer byaddr, /* vector of system service routines */
pointer byaddr, /* system service routine parameter */
fixed bin(31) byaddr, /* return code */
fixed bin(31) byaddr /* reason code */
)
limited
based( ptradd(csrt(19),16) )
returns( fixed bin(31) byvalue);

For each of these services there are also stubs available in SYS1.CSSLIB. It might be more
according to the rules in your shop to access the XML System Services through these stubs.
You then need to include the SYS1.CSSLIB in your SYSLIB concatenation in the step the
binding of your program takes place. The Call 2 statement is the trigger to generate an
indication for the Binder to include this service from SYS1.CSSLIB. Example 9-22.

Example 9-22 Defining a service using the options() in PL/I


dcl
gxl1qxd entry (
fixed bin (63) byaddr , /* work area for qxd */
fixed bin(31) byaddr , /* work area length */
pointer byaddr, /* input buffer */
fixed bin(31) byaddr , /* input buffer length */
pointer byaddr , /* pointer to return_data */
fixed bin (31) byaddr , /* return code */
fixed bin (31) byaddr /* reason cide */
)
options (asm , inter, retcode ) 1;

132 XML Processing Options on z/OS


call gxl1qxd ( qxdw(1) , 2
gxl_min_qxdwork_size,
addrdata(xmldocument) ,
length(xmldocument),
p_qxdanswer,
return_code,
reason_code ) ;
put skip list ('plretv() returns ', pliretv());

For PL/I the ’retcode’ 1 in the options() part of the declaration is the indicator to later have the
return code available. According to the linkage conventions, it is returned in register 15.

We used the compile, bind, and go procedure IBMZCBG as it is provided by IBM. See
Example 9-23, the SYS1.CSSLIB is added using JCL override. 1

Example 9-23 PL/I compile, bind and go with modification to include SYS1.CSSLIB
//GXLCLG4 JOB (999,POK),NOTIFY=HDM,REGION=0M,
// CLASS=A,MSGCLASS=T,MSGLEVEL=(1,1)
/*JOBPARM SYSAFF=SC80 << keep it on our test system
/* procedure to compile, bind and execute a pl/i program
//*PROC JCLLIB ORDER=(IBMZ.SIBMZPRC)
//G EXEC IBMZCBG,LNGPRFX='IBMZ',
// PARM.PLI='SOURCE,OPTIONS,OBJECT,NEST,XREF',
// PARM.BIND='XREF,COMPAT=MIN,LIST=ALL,MAP'
//PLI.SYSIN DD DISP=SHR,DSN=HDM.SG7810.SOURCE(GXL4)
//BIND.SYSLIB DD
// DD DISP=SHR,DSN=SYS1.CSSLIB 1
//GO.XMLIN DD DISP=SHR,DSN=HDM.SG7810.XML0100K

For examples of COBOL invoking z/OS XML System Services, see B.4, “Enterprise COBOL
program to query XML document declaration” on page 180 and B.5, “C program to query
XML document declaration” on page 183.

9.2.2 C/C++ language bindings


XML System Services provides also a set of bindings that conform to a C/C++ style of coding.
We will concentrate here on the usage of these with C, but they can also be used from C++.
All headers that define the functions contain a necessary extern C, which makes them
callable from a program written in C++.

The C/C++ application programming interface also supports Language Environment.

All header files can be found in /usr/include when you are in the z/OS UNIX. At that place
they can also be included into a batch job that compiles a program using XML System
Services. The headers are also stored in SYS1.SIEAHDRV.H and can be accessed from
there.

C/C++ programs using XML System Services need to have set the Language Environment
option XPLINK turned on. This can be achieved by exporting the environment variable
_CEE_RUNOPTS="XPLINK(ON)". Another way to turn this option on is to add a #pragma
option to the C/C++ program. See Example 9-24 on page 134.

Chapter 9. Hints, tips, and samples 133


Example 9-24 Turning on the XPLINK link from within a C/C++ program
#pragma runopts(XPLINK(ON))

#include <gxlhosrg.h>
#include <gxlhxec.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

A C/C++ program needs to be compiled with the dll option turned on. Further, to link with
routines provided by XML System Services you need to include these with the DLL’s definition
side deck files (.x) from /usr/lib. See Example 9-25.

Example 9-25 Command to compile and link a C/C++ program from the z/OS UNIX shell
HDM § SC80:/u/hdm/sg7810>cat mk
c89 -o gstridtab -Wc,dll gstridtab.c /usr/lib/gxlxxml1.x /usr/lib/gxlxosr1.x
HDM § SC80:/u/hdm/sg7810>

From /usr/lib they are also accessible for batch jobs to compile and bind a C/C++ program.
If you prefer to use a partitioned data set, the side files are stored in SYS1.SIEASID.

The dlls can be found in /usr/lib. They are also contained in SYS1.SIEALNKE.

134 XML Processing Options on z/OS


10

Chapter 10. Performance recommendations


and cost perspectives
Even though the XML language is simple in structure, XML parsing and validation can use
significant CPU cycles. This chapter presents some general performance guidelines for
handling XML documents on z/OS.

© Copyright IBM Corp. 2009. All rights reserved. 135


10.1 Where and when to validate
When receiving a XML document, most tools give you the option of validating for
well-formedness only or for full XML validation according to DTD or schema. The choice is
yours, but you should adhere to the following general rules:
򐂰 Always Validate XML
– If you receive XML from an un-trusted source
– If invalid XML is a risk and needs to be avoided
– If the application is unable to handle an invalid XML document
򐂰 Consider avoiding validation
– If you receive XML from a trusted source and the XML documents are valid
– If you have to maximize performance
– If your application are able to handle non valid XML data
򐂰 Where to validate
– As early as required to avoid application errors
– Avoid validation more than once
– Use infrastructure to validate rather than the application

10.2 XPLINK
Extra Performance Linkage (XPLINK) is a z/OS feature that provides high performance
subroutine call and return mechanisms. This results in short and highly optimized execution
path lengths.

Object oriented programming is built upon the concept of sending messages to objects that
result in the object performing some actions. The message sending activity is implemented as
a subroutine invocation. Subroutines, known as member functions in C++ terminology, are
normally small pieces of code. The characteristic execution flow of a typical C++ program is,
of many subroutine invocations to small pieces of code. Programs of this nature benefit from
the XPLINK optimization technology.

MVS has a standard subroutine calling convention which can be traced back to the early days
of System/360. This convention was optimized for an environment in which subroutines were
more complex, there were relatively few of them, and they were invoked relatively infrequently.
Object oriented programming conventions have changed this. Subroutines have become
simpler but they are numerous, and the frequency of subroutine invocations have increased
by orders of magnitude. This change in the size, numbers, and usage pattern of subroutines
made it desirable that the system overhead involved be optimized. XPLINK is the result of this
optimization.

To avoid performance penalties from swapping between XPLINK and non XPLINK
environments, you be must careful to bind your application to the correct environment.

10.2.1 XML Toolkit for z/OS


The XML Parser, C++ Edition and the XSLT Processor, C++ Edition library files, and
sidedecks are provided in both an XPLINK and a non-XPLINK version. The XML Toolkit is
provided in both XPLINK and non-XPLINK routines. This enables its use within C, C++,
Assembler, COBOL, or PL/I. You can choose the non-XPLINK version if your application is
coded in COBOL or PL/I.

136 XML Processing Options on z/OS


Due to the nature of the toolkit functionality, there will be many communications between the
application and the toolkit. So you must choose the application bind option with care.

10.2.2 z/OS XML System Services


z/OS XML is prepared using XPLINK. Linking the calling program with XPLINK is the optimal
solution. But you can call XML System Services from a non-XPLINK application if you set the
following option:
export _CEE_RUNOPTS="XPLINK(ON)

If you call z/OS XML System Services directly and not through the toolkit, the number of
environment swaps will be relatively small and the effect on the overall performance should
be minimal.

10.2.3 COBOL and PL/I built-in parsers


These parsers use the assembler interface to call XML System Service and will not suffer for
any XPLINK environment swapping penalties.

10.3 zIIPs and zAAPs


XML workloads can benefit by running on System z specialty processors. Here we discuss
the zIIP and the zAAP.

10.3.1 zAAP
The IBM System z Application Assist Processor (zAAP) is available on all IBM System z10™,
IBM System z9®, IBM eServer™ zSeries® 990 (z990), and IBM eServer zSeries 890 (z890)
systems. The zAAP specialty engine provides an attractively priced execution environment for
new Web-based applications and SOA-based technologies, such as:
򐂰 Java
For customers who desire the powerful integration advantages and traditional qualities of
service of the IBM mainframe platform.
򐂰 XML
For customers who desire cost effective XML parsing services on z/OS, z/OS XML
System Services, when running in task (TCB) mode, can exploit the zAAP for eligible XML
workloads.

In addition, the IBM XML Toolkit for z/OS V1.9 was enhanced so eligible workloads can use
z/OS XML System Services non-validating parsing. This means eligible XML Toolkit
processing (for non-validating parse requests) can exploit the zAAP and also obtain improved
performance. This function is available on the XML Toolkit for z/OS V1.9 with PTFs UA40707
and UA40708.

With XML Toolkit for z/OS v1.10 you are able to perform validating parsing using z/OS XML
System Service as the underlying parser and gain the zAAP offload advantages. Validating
parsing using z/OS XML System Services is different from validating parsing using the XML
Toolkit for z/OS alone.

Chapter 10. Performance recommendations and cost perspectives 137


IBM Enterprise COBOL V4.1 was enhanced with a new XML parse facility that allows the
optional use of z/OS XML System Services and the zAAP, when present. Enterprise COBOL
V4.2 provided an additional enhancement of validating parsing support, using z/OS XML
System Services and the zAAP, when present.

IBM Enterprise PL/I V3.8 was enhanced with a new XML parse subroutine, PLISAXC, which
allows the optional use of z/OS XML System Services and the zAAP, when present.

10.3.2 zIIP
The IBM System z Integrated Information Processor (zIIP) is available on all System z10 and
System z9 servers. It is designed to help free-up general computing capacity and lower
overall total cost of computing for select data and transaction processing workloads for
business intelligence (BI), ERP and CRM, and select network encryption workloads on the
mainframe. When executed in SRB mode, XML System Services for both validating and
non-validating parsing is offloaded to the zIIP, when present.

10.3.3 zAAP on zIIP


XML parsing performed by XML System Services running in task (TCB) mode is always
eligible to run on a zAAP. However, such processing can run on a zIIP in the case of zAAP on
ZIIP. This means that if your installation has only zIIP processors installed and initially there is
not enough work to justify a zAAP processor, it is possible to run zAAP-eligible work on a zIIP
processor. This capability is available with z/OS 1.11 and with z/OS 1.9 and z/OS 1.10
through PTFs.

Figure 10-1 summarizes the circumstances under which a zIIP or a zAAP can process an
XML workload.

Workload examples MVS Redirect Requirements


Execution
Mode
- Any software using z/OS XML System TCB zAAP 100% of z/OS XML System z/OS 1.7
Services non validating parsing Services parsing eligible for zAAP XML Toolkit for z/OS v1.9
- XML Toolkit for z/OS parsing workloads Enterprise COBOL V4.1
using z/OS classes PL/1 V3.8
- Enterprise COBOL, using XMLPARSE DB2 V9 New Function Mode
option
CICS TS 4.1
- Enterprise PL/1
- CICS Web Services/SOAP
DB2 v.9 inserting/saving XML data using SRB zIIP Same % as the zIIP eligible work z/OS 1.8
DRDA via TCP/IP (DRDA) DB2 V.9 New Function Mode

Any software using z/OS XML System SRB zIIP 100% of z/OS XML Systems z/OS 1.7
Services non validating parsing Services parsing eligible for zIIP DB2 V9 New Function Mode

Any software using z/OS XML System TCB zAAP 100% of z/OS XML System z/OS 1.9
Services validating parsing Services parsing eligible for zAAP XML Toolkit for z/OS v1.10
Enterprise COBOL V4.2
DB2 V9 New Function Mode
Any software using z/OS XML System SRB zIIP 100% of z/OS XML System z/OS 1.9
Services validating parsing Services parsing eligible for zAAP DB2 V9 New Function Mode

Applications using Java-based XML parser TCB zAAP 100% of Java-based XML parsiing Any z/OS, system z processor with
in IBM SDK eligible for zAAP zAAP support
Any software performing XML
parsing/processing I Java

Figure 10-1 XML processing eligible for zAAP or zIIP

138 XML Processing Options on z/OS


10.4 Encoding
Working with XML applications on z/OS, consider the special requirements regarding code
page conversion for the XML tools. See Chapter 11, “XML and character encoding issues” on
page 145 for a more detailed discussion of character encoding issues related to XML.

10.4.1 XML Toolkit for z/OS


This always converts the XML input string to Unicode, UTF-16, before parsing the document.
Output from the parser is always provided in UTF-16.

10.4.2 z/OS XML System Services


During a validating parse, in the current implementation, this will convert the XML document
to Unicode, UTF-8. Output from the parser will be delivered in the same encoding as the
input. For a non-validation parse no character conversion will take place. For a complete list of
acceptable codepages see Appendix A, “Supported character encoding” on page 163.

10.4.3 COBOL and PL/I built-in parsers


These parsers do not perform any automatic conversions during the XML parsing process.

10.5 Application language


The different application languages used on z/OS offer different function options to the
application developer regarding XML parsing, validation, and transformation.

The next topics give you an overview of how to optimize the infrastructure to get maximum
benefit from your System z installation by the use of the zAAP speciality engine.

Chapter 10. Performance recommendations and cost perspectives 139


10.5.1 COBOL
From a COBOL application you have several options for handling XML. Figure 10-2 shows the
main possibilities.

COBOL Application

COBOL Built-in parser

CICS WEB Services

XML Toolkit

XML System services XML System services

General General General


zAAP zAAP zAAP zAAP
Purpose Purpose Purpose
CPU CPU CPU CPU
CPU CPU CPU

Figure 10-2 Overview XML processing from COBOL application

If you use the built-in parser in COBOL to process XML documents, you must migrate to
COBOL compiler version 4.1 to take advantage of the zAAP offload engines.

CICS Web Services from version 4.1 uses XML System Services as the parsing mechanism
for some of its processing. This is offloaded to a zAAP if one is available. CICS TS 3.2 and
lower versions do not have this enhancement.

If you call XML Toolkit for z/OS from a COBOL application you have two options:
򐂰 Using z/OS specific classes or standard classes
򐂰 XPLINK or non-XPLINK

If you have access to an offload engine, choose the z/OS-specific classes to gain the lower
CPU cost on the zAAP processor.

Use the non-XPLINK versions of the parser library to eliminate the overhead from
environment swapping.

10.5.2 PL/I
As in COBOL you have a number of choices when handling XML documents in a PL/I
application. Figure 10-3 on page 141 outline the main possibilities.

The more current your IBM software inventory, the more you can take advantage of the zAAP
offload engines.

140 XML Processing Options on z/OS


PL/I Application

PL/I Built-in parser

CICS WEB Services

XML Toolkit

XML System services XML System services

General General General


zAAP zAAP zAAP zAAP
Purpose Purpose Purpose
CPU CPU CPU CPU
CPU CPU CPU

Figure 10-3 Overview XML processing from PL/I Application

Enterprise PL/I for z/OS V3R8 provides the option to use z/OS XML System Services as the
underlying parsing technology and thereby enables you to offload the parsing process to the
zAAP specialty engine.

CICS TS 4.1 is required to offload CICS Web Services XML parsing work to a zAAP
processor.

The options when calling the Toolkit from a PL/I application are similar to COBOL:
򐂰 Using z/OS-specific classes or standard classes
򐂰 XPLINK or non-XPLINK

If you have access to an offload engine, choose the z/OS-specific classes to gain the lower
CPU cost on the zAAP processor.

Use the non XPLINK versions of the parser library to eliminate the overhead from
environment swapping.

10.5.3 C and C++


The interface to XML Toolkit is C++. An application coded in C or C++ is the natural and
optimal choice, in combination with XPLINK binding. There is no built-in parser functionality in
C or C++, but you still have the option to use CICS Web Services or to call z/OS XML System.

Services directly. C or C++ programs running in TCB mode and directly invoking XML System
Services are eligible for offload to the zAAP processor. Such programs running in SRB mode
are eligible for offload to the zIIP processor.

Chapter 10. Performance recommendations and cost perspectives 141


See Figure 10-4.

C/C++ Application

CICS Web Services

XML Toolkit

XML System services

General zAAP or General


zAAP zAAP
Purpose zIIP Purpose
CPU CPU
CPU CPU CPU

Figure 10-4 Overview XML processing from C or C++ Application

CICS TS 4.1 is required to offload CICS Web Services work to a zAAP.

10.5.4 Assembler
The interface to the XML Toolkit is C++, so an Assembler application (see Figure 10-5) must
use Language Environment bindings to call the C++ API. Assembler programs running in
TCB mode and directly invoking XML System Services are eligible for offload to the zAAP
processor. Such programs running in SRB mode are eligible for offload to the zIIP processor.

Assembler Application

CICS Web Services

XML Toolkit

XML System services

General zAAP or General


zAAP zAAP
Purpose zIIP Purpose
CPU CPU
CPU CPU CPU
Figure 10-5 Overview XML processing from Assembler application

CICS TS 4.1 is required to offload CICS Web Services work to zAAP.

142 XML Processing Options on z/OS


10.5.5 Java
The natural choice for a Java application is to use the built-in Java classes for XML parsing,
validation, and generation. While the Java classes do not use z/OS XML System Services, all
Java is zAAP-enabled. A Java application that uses z/OS XML System Services is possible,
but less attractive because of the overhead of transitioning between Java and non-Java
environments. Java applications can also run in CICS using its Web services interface. See
Figure 10-6.

Java Application

CICS Web Services

Native XML
Java classes

XML System Services

General General
zAAP zAAP zAAP zAAP
Purpose Purpose
CPU CPU CPU CPU
CPU CPU

Figure 10-6 Overview XML processing from Java application

Chapter 10. Performance recommendations and cost perspectives 143


144 XML Processing Options on z/OS
11

Chapter 11. XML and character encoding


issues
This chapter starts with a brief, general discussion on character encoding, followed by
discussion of XML and System z. We include samples to demonstrate the usage of different
encoding schemes in XML documents and their use on System z.

© Copyright IBM Corp. 2009. All rights reserved. 145


11.1 Introduction
In today’s era of the Internet, multi-lingual sites and software installations are quite ubiquitous.
XML is designed to handle requirements catering to internationalization. This chapter
describes the support for internationalization on System z.

11.1.1 Definitions
We start with some basic definitions.

Character
A character is an “atomic” symbol used in a language.

Character set
A character set is a collection of all characters that comprise a given language. The language
might be a conventional human language or an unconventional language such as musical
symbols, Morse code, Braille, mathematical symbols, and so forth.

Coded character set


A character set (as defined above) where every character has been assigned a unique
number. IBM normally uses the term code page. Units of a coded character set are also
known as code points.

Character encoding
A scheme that maps a character to bytes on a computer. For example, the ISO 88591 series
of standards (IS0 8859-1, ISO 8859-2, and so forth) uses 8-bit for encoding characters and is
popular because it is usually sufficient for the English and other Latin-based languages.

Coded Character Set ID (CCSID)


IBM uses the term Coded Character Set ID (CCSID) to convey the encoding information. The
CCSID is a 16-bit number identifying a specific set of encoding scheme identifier, character
set identifier(s), code page identifier(s) and additional coding-related required information that
uniquely identifies the coded graphic character representation used. For more information,
visit the following Web page:
http://www-01.ibm.com/software/globalization/ccsid/ccsid_registered.jsp

ASCII
ASCII stands for American Standard Code for Information Interchange. It is a 7-bit character
encoding scheme based on ordering of English alphabet. It was the most widely used
encoding scheme in computers until it was surpassed by UTF-8.

1 ISO/IEC 8859 is a joint ISO and IEC series of standards for 8-bit character encoding. The series of standards
consists of numbered parts, such as ISO/IEC 8859-1, ISO/IEC 8859-2, and so forth. There are 15 parts, excluding
the abandoned ISO/IEC 8859-12. The ISO working group maintaining this series of standards has been
disbanded.

ISO/IEC 8859 parts 1, 2, 3, and 4 were originally Ecma International standard ECMA-94.

In June 2004, the ISO/IEC working group responsible for maintaining eight-bit coded character sets disbanded and
ceased all maintenance of the ISO/IEC 8859 series. In the area of character encoding, ISO now concentrates on
the Universal Character Set (ISO/IEC 10646).

146 XML Processing Options on z/OS


EBCDIC
EBCDIC (Extended Binary Coded Decimal Interchange Code) is an 8-bit character encoding
scheme used on IBM mainframe operating systems such as z/OS, OS/390, VM, and VSE as
well as IBM midrange computer operating systems such as OS/400® and i5/OS®.

Unicode
Unicode is a universal computing industry standard that codifies characters of most
languages used with computers. The various encodings of the character sets in Unicode are
referred to as Unicode Transformation Format (UTF). For example, UTF-16, UTF-8,
UTF-EBCDIC, and so forth.

Whitespace
The term whitespace refers to characters that do not have a visual mark when displayed but
still occupy space or memory. The most common example is the space character (Unicode
U+0020, EBCDIC x’40’, and so forth). Other examples can be carriage return (CR), line feed
(LF) and horizontal tab, and so forth. The XML 1.0 specification allows usage of the following
whitespace characters:
򐂰 HORIZONTAL TAB (U+0009)
򐂰 LINE FEED (U+000A)
򐂰 CARRIAGE RETURN (U+000D)
򐂰 SPACE (U+0020)

Note:
򐂰 The most common end of line character on z/OS is the newline (NEL) character. It is
x’15’ in EBCDIC and x’85’ in Unicode. For example, on z/OS, the \n string in C
converts to NEL and is often inserted in byte-oriented file systems such as
Hierarchical File System (HFS).
򐂰 The XML 1.1 specification supports NEL and the z/OS XML System Services parser
is compliant.
򐂰 The XML Parser, C++ Edition accepts documents with NEL as line termination
characters. They are normalized to LF by the parser.
򐂰 When using z/OS XML System Services, the NEL will be normalized to EBCDIC NL
characters.
򐂰 NEL is not allowed in the XML 1.0 recommendation, but is nevertheless supported
in the toolkit and XMLSS.

BOM
BOM (Byte Order Mark) has the Unicode code-point U+FEFF and is also referred to as
Zero-Width No-Break Space. This character is used to denote the endianness of the text
encoded in either UTF-16 or UTF-32. The BOM is placed as the first characters to indicate
the endianness of the file or character stream. It will be placed as x’FEFF’ to indicate big
endianness and as x’FFEF’ to indicate little endianness.

11.2 UTF schemes and System z


XML is designed to cater to multiple languages, which makes encoding an important
consideration. The UTF (Unicode Transformation Format) is a universal standard with wide
adoption. Using UTF for encoding XML documents is recommended. However, it is not
mandatory to use UTF for XML character encoding so long as the encoding value is both
valid and understood by all senders and receivers.

Chapter 11. XML and character encoding issues 147


11.2.1 Advantages of using Unicode
Use of Unicode has certain advantages:
򐂰 Support for a vast number of languages
򐂰 Ease of information exchange across heterogeneous systems
򐂰 Ease of decoding on multiple platforms
򐂰 Avoids use of escape sequences. For example, using &#x20AC; instead of ? symbol or
using &rlm; for RIGHT-TO-LEFT MARK character that is not visible.
򐂰 Avoids character translation errors common for ASCII to EBCDIC and EBCDIC to ASCII
conversions
򐂰 Avoids common errors due to incorrect assumptions about which ASCII or which EBCDIC
character set is in use

11.2.2 Character encoding schemes supported on System z


The z/OS XML System Services supports several code pages. For a complete list that
includes EBCDIC variants, see Appendix A, “Supported character encoding” on page 163.

An XML document can be encoded in any scheme. What is required is for all parties creating
and consuming the XML document to agree upon the names used in the encoding=
declaration of the document. To ensure, a common set of encoding names are used, consider
using the character sets described in IANA2 (Internet Assigned Numbers Authority).

UTF-8
UTF-8 (8-bit UCS/Unicode Transformation Format) is a multi-byte encoding scheme for
Unicode that can represent any character in the Unicode character set. It provides backward
compatibility with ASCII. The CCSID for UTF-8 is 1208.

UTF-8 is also a variable length character encoding scheme. Some characters require only
one byte, some two, some three or more. UTF-8 is backward compatible with ASCII in that the
first 127 characters are mapped identically to ASCII.

UTF-16BE
UTF-16 (16-bit UCS/Unicode Transformation Format) is a variable length encoding scheme
for Unicode that maps each character to one or two 16-bit words. The CCSID for UTF-8 is
1200.

UTF-16BE (Big Endian) is one of two UTF-16 encoding schemes. UTF-16BE and UTF-16LE
(little endian) differ only in the order of the bytes for a character. UTF-16BE is the preferred
encoding for System z. UTF-16LE can be converted to UTF-16BE when required.

11.2.3 z/OS XML Toolkit and z/OS XML System Services


In this section we describe considerations for using the z/OS XML Toolkit with z/OS XML
System Services.
򐂰 Both XML specifications (XML 1.0 and XML 1.1) are supported by z/OS XML System
Services and XML Parser, C++ Edition.
򐂰 For EBCDIC code pages, z/OS XML System Services will accept XML 1.0 documents with
the newline character.
2 List of character sets: http://www.iana.org/assignments/character-sets

148 XML Processing Options on z/OS


򐂰 Because XML documents with newline character are non-compliant with the XML 1.0
specification, such documents should not be used when interfacing with external systems.
When sending to an ASCII based system, one can use iconv() to convert the newline
character to the ASCII LF (line feed) character. Example 11-1 converts from IBM-037
CCSID to ASCII (or, ISO8859-1). For more information, see z/OS Support for Unicode:
Using Unicode Services, SA22-7649.

Example 11-1 iconv() syntax for converting to different code set


iconv -f IBM-037 -t ISO8859-1 sample.xml > sample.asc.xml

Important: After doing this conversion, be sure to update the encoding= statement in
the new document to reflect the new encoding.

򐂰 The XML Toolkit will always convert XML documents into UTF-16BE before beginning the
parsing.
򐂰 The XML Toolkit will return parsed data in UTF-16BE regardless of the encoding of the
input data stream.
򐂰 The z/OS XML System Services expects the XML document to be in one of the supported
CCSID as listed in Appendix A, “Supported character encoding” on page 163”. The output
parsed data stream is the same as the passed CCSID. To determine the CCSID of the
XML document, assembler API GXL1QXD (31 bit) or GXL4QXD (64 bit) can be called. For
more information see z/OS XML System Services User’s Guide and Reference,
SA23-1350.

11.2.4 Enterprise COBOL


Enterprise COBOL for z/OS V3R1 provides the XML PARSE statement to parse a XML
document.

Determining the character encoding


Before parsing, the parser must know the character encoding of the XML document. The
encoding of the document can be determined in multiple ways. One way of obtaining the
encoding information is the datatype of the data item holding the XML document. If the data
item is a national item (PIC N, USAGE NATIONAL, GROUP-USAGE NATIONAL) the
encoding is assumed to be UTF-16BE (CCSID 1200). For XML streams residing within
non-national data items, the character encoding is assumed to be the program’s native
character set, as specified with the CODEPAGE compile option

With the XMLPARSE(XMLSS) option in effect, the encoding might also be determined with
the optional ENCODING phrase in the XML PARSE statement. When XMLPARSE(COMPAT)
is in effect, the encoding might also be determined by inspecting the first few bytes of the
document or the encoding declaration in the XML document.

Chapter 11. XML and character encoding issues 149


Supported code pages
The following list details some considerations while doing a parse with XML PARSE
statement.
򐂰 When the XML document is contained in a national data item (PIC N, USAGE IS
NATIONAL, GROUP-USAGE NATIONAL) then the supported encoding is UTF-16BE
whose CCSID is 1200. This is regardless of the XMLPARSE compiler option.
򐂰 When the XML document is contained in an alphanumeric item:
– with XMLPARSE(XMLSS) compiler option and RETURNING NATIONAL phrase is
specified in XML PARSE statement
• UTF-8
• Any EBCDIC code page
• Any ASCII code page supported by z/OS Unicode Services for conversion to
UTF-16. See Appendix B in z/OS Support for Unicode: Using Unicode Services,
SA22-7649.
– With XMLPARSE(XMLSS) compiler option and RETURNING NATIONAL phrase is
omitted in XML PARSE statement, then UTF-8 and any of the single byte EBCDIC
code pages listed in Appendix B.
– With XMLPARSE(COMPAT) compiler option, see the list of supported code pages in
Appendix B, “Program source files” on page 165.

Encoding overrides
When the XMLPARSE(XMLSS) compiler option is in effect, some items might not be in effect
or might be superseded by something else. These are listed:
򐂰 Any encoding declaration in the XML document is ignored.
򐂰 When the XML document is in a national data item, then the encoding is determined as
UTDF-16BE (CCSID 1200). Therefore, the optional ENCODING phrase in XML PARSE
statement must be omitted or be specified with value as 1200. Also, the CODEPAGE
compiler option is ignored in this case.
򐂰 If the XML document is in a alphanumeric data item, then the CCSID value mentioned in
the optional ENCODING phrase of the XML PARSE statement takes precedence over the
CODEPAGE compiler option.

Generating XML
The option for generation of an XML document is also available in z/OS Enterprise COBOL
V3R3 with the XML GENERATE statement. The encoding considerations when generating an
XML document are as follows:
򐂰 When the optional ENCODING phrase is omitted, the encoding of the generated XML
document is determined by the data type of the receiving item. If the receiving item is
alphanumeric, then the encoding is as mentioned in CODEPAGE compiler option. If the
receiving item is of national type, then the encoding is UTF-16BE (CCSID 1200).
򐂰 When the optional ENCODING phrase is specified, then it must be one of the following
choices:
– 1200 (UTF16-BE) if the receiving item is of type national.
– 1208 (UTF-8) if the receiving item is of type alphanumeric.

150 XML Processing Options on z/OS


BOM
A BOM is not generated by the XML GENERATE statement.

With the XMLPARSE(COMPAT) compiler option, an exception will be raised if the XML
declaration does not begin at the first byte. Thus, BOM is not accepted for parsing.

For more details on handling XML data in COBOL, refer Enterprise COBOL for z/OS,
Language Reference Version 4 Release 1, SC23-8528 and Enterprise COBOL for z/OS,
Programming Guide Version 4, Release 1, SC23-8529.

11.2.5 Enterprise PL/I


Enterprise PL/I for z/OS V3R8 provides built-in support for XML with the aid of sub-routines
PLISAXx (x=A, B or C).

Determining encoding
Broadly speaking, the encoding of the XML document is determined by the routine by looking
at three places. First, the document is inspected for the first few bytes to look for the basic
encoding. Second, the routines look for the encoding attribute in the XML declaration, if
specified. Third, the PLISAX call is examined to determined the code page value. If it is
omitted, then the default or specified value of CODEPAGE compiler option will be used.

Supported code pages


Other considerations with respect to encoding need be made as shown below.
򐂰 The routines PLISAXA and PLISAXB do not have support for UTF-8 documents. Only
UTF-16 documents and certain single-byte code pages are supported. See Appendix B,
“Program source files” on page 165, for the list of supported code pages.
򐂰 The PLISAXC routine supports UTF-8, UTF-16 and certain single-byte code pages
documents.

For more information about these routines, see Enterprise PL/I for z/OS Programming Guide,
SC27-1457.

Encoding overrides
If the value of code page specified in the PLISAX call is omitted then the value specified (or
obtained as a default) in the CODEPAGE compiler option will be in effect.

Generating XML
These routines do not support generation of XML. To generate XML, the built-in function
XMLCHAR must be used.

BOM
The BOM is neither inserted by the XMLCHAR built-in function nor is it honored by the
routines for parsing.

Chapter 11. XML and character encoding issues 151


11.3 Encoding examples
Broadly speaking, there are two types of character encoding, namely variants of Unicode and
variants of EBCDIC. Only these encodings will be discussed.

Before the sample applications are described, the XML files being used are shown
throughout this section. These XML files have been saved in a z/OS UNIX file system for
convenience. These files could have been saved in traditional MVS datasets as well.

In z/OS XML System Services, the GXL1QXD (GXL4QXD) service will report the XML
declaration in the document. This report will be based on the structure of GXLYQXD. B.5, “C
program to query XML document declaration” on page 183 shows the COBOL source for
calling this service. Each of the samples in this section show an XML document and report
created out of calling the service. The report has been split into two parts: the first part does
not report the XML flags, whereas the second part reports them in hexadecimal display. The
first part also shows the length of the document read that is not a part of the output structure
but is being emitted by the COBOL program. Refer to z/OS XML System Services User
Guide, SA23-1350 to learn more about the service and the output structure.

11.3.1 EBCDIC XML document


To create a XML document in EBCDIC, ISPF editor can be used to create the document in
z/OS UNIX or in native MVS datasets. The document shown in Example 11-2 shows a simple
XML document with alphabets from the German and Danish languages. To edit in ISPF,
ensure that the code page 1141 is enabled for the host. For this particular example, sending
the file from a PC through FTP is probably not a good idea because of end of line characters.
Otherwise, with FTP and binary transfer option turned off, a valid XML document can be still
created in z/OS UNIX. It can be copied into a z/OS Unix file system as
$HOME/xml/sample-ibm01141.xml.

Example 11-2 XML document with EBCDIC encoding


<?xml version="1.0" encoding="IBM01141" standalone="yes"?>
<root>
<greetings>
<sample useLang="English">Greetings</sample>
<sample useLang="Deutsch">Grüßen</sample>
<sample useLang="Danish">KÆrlig Hilsen</sample>
</greetings>
</root>

152 XML Processing Options on z/OS


Notes:
򐂰 The value of the encoding parameter is set to IBM01141 which covers German
alphabet and the euro symbol as well. In general, when deciding on a encoding
attribute value, it will help to look up the list of supported encodings and then look up
the IANA list.
򐂰 Note the characters ü,ß and Æ. Suppose the encoding attribute IBM037 were being
used. Because this code set does not have the German alphabet, these characters
would have to be entered as an entity.
򐂰 Using iconv() on this file to convert from EBCDIC to ASCII will convert the line
termination characters to x’0A’.

If this XML document were to be received onto a PC using FTP (with or without binary
transfer option) and viewed in an editor that shows all characters (such as a hex editor),
then the line termination characters.They will be seen as x’0A’ with translation and x’15’
without translation.

When this file is passed as input to the COBOL program calling the GXL1QXD service,
Example 11-3 and Example 11-4 show the results obtained.

Example 11-3 Result of GXL1QXD service for IBM01141 encoded XML document
Buffer Length : 000000226
QXD Version : 1
XML Autodet Value : 8
XML Autodet CCSID : 37
XML Version : 1
XML Release : 0
XML Spec CCSID : 1141
XML Reserved : 0
XML Decl Length : 58

Example 11-4 Result (XML flags) of GXL1QXD service for IBM01141 encoded XML document
XML Flags 1 : Ø
EDD4C988A4F44444447484
743063172010000000A000
----------------------
XML Flags 2 : Ö
EDD4C988A4F444444474E4
743063172020000000A000

As per this response, the parser accomplishes the following goals


򐂰 Was able to auto-detect the encoding type to be of EBCDIC.
򐂰 Was able to auto-detect the CCSID as 37.
򐂰 Reported the version and release that was mentioned in the document. If it were not
mentioned, it would have defaulted to 1.0 and reported likewise.
򐂰 Reported the specified CCSID in the XML declaration as 1141.
򐂰 Reports the first flag as x’80’, that is, only the first bit of the flag (1000 0000) is turned on.
It means, the standalone=”yes” was mentioned in the declaration.

Chapter 11. XML and character encoding issues 153


򐂰 Reports the second flag as x’E0’, that is, the first three bits of the flag (1110 0000) are
turned on. This means, all the attributes standalone, version and encoding were
mentioned in the XML declaration. If some of these attributes were not mentioned, then
default values would be reported.
򐂰 Reports the length of XML declaration to be of 58 bytes

11.3.2 UTF-8 XML document


The UTF-8 encoding is the most popular encoding around. To test for this encoding, you can
use our tools we provided in Appendix B.4, “Enterprise COBOL program to query XML
document declaration” on page 180 or a C program that can be installed in the z/OS UNIX
environment.

As UTF-8 is available in the Windows and Linux environment, you can use simple editors on
these platforms. In Windows Notepad, this can be done by selecting UTF-8 as the Encoding
option in the “Save As” dialog box as shown in Figure 11-1.

A file encoded in UTF-8 can also be created on System z by some of the options listed as
below:
򐂰 Creating a file in EBCDIC and using iconv() for the conversion.
򐂰 Calling z/OS Unicode for conversion. See z/OS Support for Unicode: Using Unicode
Services, SA22-7649.
򐂰 Using a programming language such as COBOL, PL/I, C/C++ and achieve the translation
using the services provided by these languages.
򐂰 Saving a file in HFS with FILETAG attribute set and automatic conversion turned on (see
11.4.6, “Saving ASCII files on System z” on page 161

Figure 11-1 Windows Notepad dialog box with encoding option highlighted

154 XML Processing Options on z/OS


Example 11-5 is a sample XML document with UTF-8 encoding.

Example 11-5 XML document with UTF-8 encoding


<?xml version="1.0" encoding="UTF-8" standalone="yes"?><root><greetings>
<sample useLang="English">Greetings</sample>
<sample useLang="Deutsch">Mit freundlichen Grüßen</sample>
<sample useLang="Danish">KÆrlig Hilsen</sample>
</greetings></root>

This file should be then transferred to z/OS UNIX (for instance, $HOME/xml/sample-utf8.xml)
on z/OS with transfer type as binary. When this file is passed as input to the COBOL program
calling the GXL1QXD service, Example 11-6 and Example 11-7 show the results obtained.

Example 11-6 Result of GXL1QXD service for UTF-8 encoded XML document
Buffer Length : 000000254
QXD Version : 1
XML Autodet Value : 7
XML Autodet CCSID : 1208
XML Version : 1
XML Release : 0
XML Spec CCSID : 1208
XML Reserved : 0
XML Decl Length : 58

Example 11-7 Result (XML flags) of GXL1QXD service for UTF-8 encoded XML document
XML Flags 1 : ä
EDD4C988A4F444444474C
743063172010000000A00
---------------------
XML Flags 2 : Ö
EDD4C988A4F444444474E
743063172020000000A00

As per this response, the parser accomplishes the following goals


򐂰 Was able to auto-detect the encoding type to be of UTF-8.
򐂰 Was able to auto-detect the CCSID as 1208.
򐂰 Reported the version and release that was mentioned in the document. If it were not
mentioned, it would have defaulted to 1.0 and reported likewise.
򐂰 Reported the specified CCSID in the XML declaration as 1208.
򐂰 Reports the first flag as x’C0’, that is, the first two bits of the flag (1100 0000) are turned
on. It means, the standalone=”yes” was mentioned in the declaration and BOM was
detected. The BOM is inserted by Windows Notepad for UTF-8 files3. This can be
confirmed by opening the saved XML document on a PC in a hex editor. It will be
prepended with x’EFBBBF’. (See the last bullet in this list.)

3
For a UTF-8 file, BOM is not necessary. The Unicode standard allows for the BOM but does not recommend it. See
page 36, Chapter 2, in Unicode 5.0.0 version of the Unicode Standard.
http://www.unicode.org/versions/Unicode5.0.0/ch02.pdf

Chapter 11. XML and character encoding issues 155


򐂰 Reports the second flag as x’E0’, that is, the first three bits of the flag (1110 0000) are
turned on. This means, all the attributes standalone, version, and encoding were
mentioned in the XML declaration. If some of these attributes were not mentioned, default
values would be reported.
򐂰 Reports the length of the XML declaration is 58 because the three bytes for BOM are also
counted.

11.3.3 UTF-16BE XML document


As in the case detaile in 11.3.2, “UTF-8 XML document” on page 154, a UTF-16BE document
can be created on a PC by ensuring that the encoding chosen is UTF-16BE. When using
Windows Notepad, the encoding option in the “Save As” dialog box to be used is ‘Unicode big
endian’. With this option, every character will be saved in 16 bits in a big endian format with
the complete file prepended with the BOM as x’FEFF’. An easy way to confirm this is to take
a rough estimate of the number of characters in the file. multiply it by two (to account for
UTF-16) and add two bytes for BOM. This will give the size of the file in bytes that can be
verified by looking up the properties of the file. The document shown in Example 11-8 can be
copied into a Windows Notepad file and saved with the encoding option as ‘Unicode big
endian’.

Example 11-8 XML document with UTF-16BE encoding


<?xml version="1.0" encoding="UTF-16BE" standalone="yes"?>
<root>
<greetings>
<sample useLang="English">Greetings</sample>
<sample useLang="Deutsch">Mit freundlichen Grüßen</sample>
<sample useLang="Danish">KÆrlig Hilsen</sample>
</greetings>
</root>

This file should be then transferred to z/OS UNIX (say $HOME/xml/sample-utf16BE.xml) on


z/OS with transfer type as binary. When this file is passed as input to the COBOL program
calling the GXL1QXD service, the results shown in Example 11-9 are obtained.

Example 11-9 Result of GXL1QXD service for UTF-16BE encoded XML document
Buffer Length : 000000504
QXD Version : 1
XML Autodet Value : 5
XML Autodet CCSID : 1200
XML Version : 1
XML Release : 0
XML Spec CCSID : 1200
XML Reserved : 0
XML Decl Length : 118

Note the length of the buffer above. The XML document used in this case is same as in
example 11-5 except for the value of encoding attribute. In case of document with UTF-8
encoding, we had 251 bytes for the characters and three bytes for BOM. The 251 bytes
include 8 bytes for line feed characters and 3 bytes more for special characters which
occupied two bytes each. (Recall, UTF-8 is a variable 8-bit encoding scheme.) Thus,
multiplying 251 bytes by 2 for UTF-16 representation and adding two more bytes for BOM, we
have a total of 504 bytes.

156 XML Processing Options on z/OS


This file should be then transferred to z/OS UNIX (say $HOME/xml/sample-utf16BE.xml) on
z/OS with transfer type as binary. When this file is passed as input to the COBOL program
calling the GXL1QXD service, Example 11-10 is obtained.

Example 11-10 Result (XML flags) of GXL1QXD service for UTF-16BE encoded XML document
XML Flags 1 : ä
EDD4C988A4F444444474C
743063172010000000A00
---------------------
XML Flags 2 : Ö
EDD4C988A4F444444474E
743063172020000000A00

As per the response, the parser accomplishes the following goals:


򐂰 Was able to auto-detect the encoding type to be of UTF-16 big endian.
򐂰 Was able to auto-detect the CCSID as 1200.
򐂰 Reported the version and release that was mentioned in the document. If it were not
mentioned, it would have defaulted to 1.0 and reported likewise.
򐂰 Reported the specified CCSID in the XML declaration as 1200.
򐂰 Reports the first flag as x’C0’, that is, the first two bits of the flag (1100 0000) are turned
on. It means, the standalone=”yes” was mentioned in the declaration and BOM was
detected. The BOM is inserted by Windows Notepad. This can be confirmed by opening
the saved XML document on a PC in a hex editor. It will be prepended with x’EFBBBF’.
(See point 7 below also.)
򐂰 Reports the second flag as x’E0’. That is, the first three bits of the flag (1110 0000) are
turned on. This means, all the attributes standalone, version, and encoding were
mentioned in the XML declaration. If some of these attributes were not mentioned, default
values would be reported.
򐂰 Reports the length of the XML declaration is 118 because there are 58 characters in the
XML declaration which will occupy 116 bytes in UTF-16 to which two bytes for BOM are
also counted.

11.3.4 UTF-16LE XML document


The UTF-16LE (little endian) encoding scheme is not supported by z/OS XML System
Services. An attempt to pass an XML document using the method shown in this section will
cause the service to respond with a return code of 8 and a reason code of x’1201’. This
reason code means an invalid CCSID was passed. See Reason Codes Listed by Value in
z/OS XML System Services User’s Guide and Reference, SA23-1350 for more details.

Chapter 11. XML and character encoding issues 157


11.4 Exchanging XML documents between heterogeneous
systems
One of the most common issues in an enterprise is the exchange of data between dissimilar
systems. For this particular discussion, we limit the scope to the character encoding of a
given system. We discuss briefly possible scenarios of exchange of data between such
systems.

We touch upon various transport protocols supported on the System z to communicate with
external systems. Then we describe the encoding considerations with regards to XML
documents. However, if the XML document were to travel around various points in an
enterprise (or outside), it is safest to have the encoding attribute specified in the document
itself rather than rely on any other mechanisms or assumptions. Should the XML document
undergo conversion, the value of the encoding attribute should be changed accordingly.

11.4.1 HTTP
The encoding information can be provided in the HTTP header itself. If character conversion
is likely, having encoding declarations in the HTTP header is better because a server or a
client might assign a higher precedence to this declaration than to an in-document
declaration. If XHTML pages are being used as XML, the meta charset declaration in the
HTTP header should not be used. It should be used for HTML or XHTML served as HTML.

A sample HTTP header is shown in Example 11-11.

Example 11-11 HTTP header with character encoding declaration


HTTP/1.1 200 OK
Date: Wed, 13 May 2009 10:46:04 GMT
Server: Apache/1.3.28 (Unix) PHP/4.2.3
Content-Location: CSS2-REC.en.html
Vary: negotiate,accept-language,accept-charset
TCN: choice
P3P: policyref=http://www.w3.org/2001/05/P3P/p3p.xml
Cache-Control: max-age=21600
Expires: Wed, 13 May 2009 16:46:04 GMT
Last-Modified: Tue, 12 May 2008 22:18:49 GMT
ETag: "3558cac9;36f99e2b"
Accept-Ranges: bytes
Content-Length: 10734
Connection: close
Content-Type: text/html; charset=iso-8859-1
Content-Language: en

11.4.2 WebSphere MQ
WebSphere MQ applications communicate with MQ servers using IBM-defined data
structures. All MQ applications contain data structures for an object description, message
description, get options, or put options. WebSphere MQ applications running on z/OS must
use the same character set as their local MQ server to view or update these data structures.
Therefore, if the z/OS MQ servers are set to use ccsid 500, each z/OS MQ application should
be written in and compiled as ccsid 500. Alternatively, the application must explicitly convert
character fields to and from the local MQ server’s ccsid and its own ccsid.

158 XML Processing Options on z/OS


MQ client programs must use their native character set for these data structures. For MQ
client programs, the data within these structures is automatically converted to the character
set required by the attached MQ server.

Every message arriving or leaving a WebSphere MQ application has an associated message


descriptor, referred to as MQMD. This message descriptor contains fields that are set by the
sending application or the sender’s queue manager. Information about each message,
including the MQMD fields, is automatically converted by each MQ queue manager to its local
character set.

Additionally, WebSphere MQ supports a number of predefined message formats, such as


distribution header, dead letter, MQ trigger message, programmable command format, IMS
bridge, CICS bridge, message descriptor extension, MQ event messages and others. When a
message receive request specifies the MQGMO_CONVERT option, MQ servers
automatically convert these predefined types upon message receipt.

Users can define their own user message types and provide corresponding conversion
routines for them. For user-defined message types, message receive requests that specify
the MQGMO_CONVERT option will invoke the user-provided conversion routines as each
message is received.

MQFMT_STRING is the format senders should designate for messages that consist solely of
displayable characters. Messages consisting entirely of XML should be sent using the
MQFMT_STRING format. When message retrieval specifies MQGMO_CONVERT for
messages sent as MQFMT_STRING, the entire message body is converted, if necessary, to
the receivers requested character set. For example, an XML message sent from an EBCDIC
ccsid 500 application that specified MQFMT_STRING is automatically converted in EBCDIC
ccsid 1047 for an application that receives messages using MQGMO_CONVERT and
requests ccsid 1047.

Receiving applications request conversion to a specific character set by setting the


CODEDCHARSETID field of the message descriptor before each GET message request.
CODEDCHARSETID is an input-output field for message receiving applications that specify
MQGMO_CONVERT. It is output only for applicaitons that do not specify
MQGMO_CONVERT. When the message is obtained and the requested conversion is
successful, a normal condition code is returned. When the message cannot be converted, the
unconverted message is returned and a warning condition code is returned.

After each GET message request, the CODEDCHARSETID field is set to the ccsid specified
by the sender for unconverted messages, or to the receiver’s requested ccsid for converted
messages.

The default (and most common) MQ message format for sending applications is
MQFMT_NONE. MQGMO_CONVERT will not convert messages of type MQFMT_NONE.
The unconverted message will be returned to the receiver with a warning condition. However,
the receiver can use the updated CODEDCHARSETID field to convert the message body
from the sender’s ccsid to the receiver’s ccsid.

Note that character set conversion with or without MQGMO_CONVERT might corrupt the
byte-order-marks (BOM) of XML Unicode documents.

See more in WebSphere MQ Application Programming Reference Version 6.0, SC34-6596


and WebSphere MQ Intercommunication, Version 6.0, SC34-6587.

Chapter 11. XML and character encoding issues 159


11.4.3 FTP
The File Transfer Protocol (FTP) is one of the most commonly used mechanisms to transfer
files from one machine to another. The FTP standard RFC959 defines the type of data to be
transferred. The types of transfer is provided to the server using the TYPE command. The
values could be an A (ASCII), E (EBCDIC), I (binary; transferred in 8-bit bytes) or L
(word-oriented transfer where word length can be provided as an argument). The type
command indicates the type of transfer, not the type in which the data is stored in the source
or destination system. It is the responsibility of the client or the server in a FTP session to
convert the data (characters, new lines, and so forth) into a format that is best understood
natively by application programs running on the platform. With binary (type I) transfers, the
files are not translated, so they arrive on the target platform with the same encoding as on the
source system.

When exchanging XML documents with System z through FTP, there are a couple of choices.
򐂰 Receive the document with translation enforced and treat the document as normal
EBCDIC data. However, it must be ensured that, the encoding attribute in the XML
declaration (if present) is not in conflict with the result of conversion.
򐂰 Receive the document with translation not enforced and treat the document as ASCII
(ISO8859-x) or Unicode data. As above, the encoding attribute in the XML declaration (if
present) should not conflict with the encoding of the document.
򐂰 If the document is being received into a Hierarchical File System (HFS) with file tagging
and automatic conversion enabled, extra care should be taken. The goal should be to
ensure that there are no unnecessary translations happening. Should the document
should undergo translation, it should not conflict with the encoding attribute in the XML
declaration, if present. See 11.4.6, “Saving ASCII files on System z” on page 161 for more
details.

11.4.4 DB2 database and encoding considerations


Beginning with Version 9, DB2 offers support for XML with pureXML. The DB2 tables can now
have XML documents in table columns of the type XML. There can be cases when XML
documents are sent or received from DB2 on System z. In such cases, it is important to know
if character conversion will be called for. If there is a chance for conversion to happen, then
the original rule still holds. That is, the result of conversion should not conflict with the
encoding of the XML document or with the value of the encoding attribute in the XML
declaration, if present.

The following examples show when character conversion could happen when exchanging
data (in general and XML documents in particular) between different servers on possibly
different platforms.
򐂰 The SQL statement maybe converted to UTF-8 for parsing when the text is passed in a
PREPARE statement in an ASCII application.
򐂰 Changing the value of special register CURRENT APPLICATION ENCODING SCHEME
to a value different from the encoding scheme of the data to be retrieved.
򐂰 Value of ENCODING option in BIND statement is different from the encoding scheme of the
target server.

When using DB2 as a Web service provider or consumer, then the SOAP message that is
exchanged should be saved in XML column of a table. Instead, if the response from a Web
service is received into a CLOB, DBCLOB, GRAPHIC, or VARGRAPHIC column, then

160 XML Processing Options on z/OS


conversion should be accounted for. This is because DB2 will encode data in CLOB columns
in UTF-8 and data in DBCLOB will be encoded as UTF-16.

See more in DB2 Version 9.1 for z/OS Internationalization Guide, SC19-1161.

11.4.5 CICS
With CICS Transaction Server for z/OS Version 3.1, the concept of containers and channels
were introduced. With the advent of containers, the limit of 32 K of a COMMAREA was
overcome to allow for exchange of larger amount of data. An application program can send or
receive any number of containers.

This feature of containers and channels is perfectly suited for exchange of large XML
documents. The CICS Transaction Server provides APIs to put (PUT CONTAINER) or get
(GET CONTAINER) data into containers with or without conversion. The code page for data
conversion is provided as a CCSID value (numeric) or one of the IANA-registered charset
name for the code page. If the code page is not mentioned, the default value is taken from
LOCALCCSID system initialization parameter. See the following Web page:
https://publib.boulder.ibm.com/infocenter/cicsts/v4r1/topic/com.ibm.cics.ts.doc/lp
aths/channels_lp_overview.html

11.4.6 Saving ASCII files on System z


In the HFS area, z/OS UNIX System Services provides file tagging to identify the codeset of
the text data within files. This file tag can be considered as meta-data associated with a file.
With file tagging, one can optionally enable automatic conversion. This can be done by setting
the _BPX_AUTOCVT environment parameter in your shell environment or use the Language
Environment runtime parameter FILETAG when running application programs.

If an ASCII file was sent in without translation and saved in the z/OS UNIX file system, the
program reading (or writing) to that file should take into account the file tag and the
enablement of automatic conversion. Another environment variable to consider when
automatic conversion is in effect is _BPXK_CCSIDS. This environment variable is a pair of
EBCDIC/ASCII CCSIDs that are used during automatic conversion.

Therefore, when a program is reading (or writing) a file from an HFS area, the data
transferred to (or written from) the program is already in the required encoding. A conversion
before a read or after a write operation is not necessary. In fact, a conversion may lead to
incorrect results. The implication of XML documents saved in HFS is the encoding of the XML
document should match with the target of conversion that will happen if automatic conversion
was in effect. This should also not conflict with the encoding attribute in the XML declaration,
if present. Neither should it conflict with what is passed for PIMA creation.

Chapter 11. XML and character encoding issues 161


When dealing with HFS files, a couple of other things need to be kept in mind.
򐂰 The shell command (since z/OS V1R7) chtag assigns, changes, and removes a tag on
existing files.
򐂰 Some shell commands have options to support file tagging and automatic conversion. The
commands are as follows:
– cp
– df
– file
– find
– head
– iconv
– localedef
– ls
– mount
– mv
– od
– pack
– pax
– strings
– tail
– tcsh
– test
򐂰 The TSO commands OCOPY, OGET, OGETX, OPUT and OPUTX have parameters to specify
conversion. If automatic conversion is in effect, these commands might not be used with
conversion option.

For more information, see the following books:


򐂰 z/OS V1R11.0 UNIX System Services Planning, GA22-7800
򐂰 z/OS V1R11.0 Language Environment Programming Reference, SA22-7562
򐂰 z/OS V1R11.0 UNIX System Services Command Reference, SA22-7802

162 XML Processing Options on z/OS


A

Appendix A. Supported character encoding


This appendix describes the list of code pages supported by z/OS XML System Services on
z/OS.

© Copyright IBM Corp. 2009. All rights reserved. 163


Supported code pages
Table A-1 describes the list of encodings supported by z/OS XML System Services. For more
details, see the following Web pages:
򐂰 http://www.iana.org/assignments/character-sets
򐂰 http://www-01.ibm.com/software/globalization/ccsid/ccsid_registered.jsp

Table A-1 List of supported encodings


CCSID Short description

1208 UTF-8 Unicode

1200 UTF-16BE (Only big endian format is supported)

1140, 37 Latin-1 / Open Systems. 1140 has support for euro. EBCDIC

1141, 273 Austria, Germany. 1141 has support for euro.

1142, 277 Denmark, Norway. 1142 has support for euro.

1143, 278 Finland, Sweden. 1143 has support for euro.

1144, 280 Italy. 1144 has support for euro.

1145, 284 Spain, Latin America. 1145 has support for euro.

1146, 285 UK. 1146 has support for euro.

1147, 297 France. 1147 has support for euro.

1148, 500 International. 1148 has support for euro.

1149, 871 Iceland. 1149 has support for euro.

164 XML Processing Options on z/OS


B

Appendix B. Program source files


This appendix provides complete program source for some of the examples used in this book.

B.1 PL/I example to generate XML


Example B-1 shows a simple program that generates a XML string from a structure. Only
some content is generated, and the necessary document header and encoding is left out.

Example B-1 also contains some code to show the conversion from one codepage into
another. Here we use the PL/I built-in function MEMCONVERT, the codes follows after the 1

Example B-1 PL/I Generate XML example


*process rules(nolaxdcl) limits(fixedbin(31,63)) display(std);
test: proc options(main);

dcl usize(0:1600) unsigned fixed bin (8) ;


dcl buffer char(800);
dcl aus(1000) unsigned fixed bin(16) ;
dcl jx fixed bin(31) init(0) ;
dcl done fixed bin(16);

dcl written fixed bin(31) init(0) ;


dcl next pointer;
dcl left fixed bin(31);
dcl 1 Personnel,
2 Name ,
3 first char(32) var,
3 last char(32) var,
2 a2,
3 country char(2),
3 redbooks fixed bin(15);

/* 1 */
first = 'Hans-Dieter'; Last = 'Mertiens' ;

© Copyright IBM Corp. 2009. All rights reserved. 165


country = 'DE' ; redbooks = 10;

next = addr(buffer);
left = stg(buffer);
written = xmlchar( Personnel, next, left );
next += written;
left -= written;
Put skip edit ( buffer ) (A(written)) ;

first = 'Mogens' ; Last = 'Conrad' ;


country = 'DK' ; redbooks = 2;

next = addr(buffer);
left = stg(buffer);
written = xmlchar( Personnel, next, left );
Put skip edit ( buffer ) (A(written)) ;
Put skip list ( written) ;

/* now convert the last buffer to utf-8 = 1208 */1


done = memconvert( addr(aus), 500, 1208 ,
addr(buffer), written, 037 );

display( '-------- source 037 ' );


do jx = 0 to written -32 by 32;
display( heximage( addr(buffer)+jx,32,' ') );
end;
display( '-------- target 1208 / UTF-8' );
do jx = 0 to written-32 by 32;
display( heximage( addr(aus)+jx,32,' ') );
end;
display( '--------' );

end; /* main */

166 XML Processing Options on z/OS


B.2 PL/I program to call z/OS XML System Services
This program is the basis for many of our examples. The version shown in Example B-2 does
not do validated parsing.

Example B-2 Simple PL/I program to parse without validation


*process rules(nolaxdcl) limits(fixedbin(31,63)) display(std);
test: proc options(main);

/* changes - include better messages (done)


avoid hard core way to address gxl services
read_xml changed to really read from a data set allocated
under XMLIN
...
*/
dcl xmlin file record sequential input ;
dcl eof fixed bin(31) init(0) ;
On Endfile(xmlin) EOF = 1 ;
dcl size fixed bin(31) static init(0500);
dcl readed fixed bin(31) static init(0);
dcl reads fixed bin(31) static init(0);
dcl (c_1301, c_1302, c_1303, c_1304) fixed bin (31) init(0);

dcl cvt pointer based( ptrvalue(16) );


dcl cvtcsrt pointer based( ptradd(cvt,544) );
dcl csrt(19) pointer based( cvtcsrt );

/* start of gxl declares */

dcl
gxl1qxd entry (
fixed bin (63) byaddr , /* work area for qxd */
fixed bin(31) byaddr , /* work area length */
pointer byaddr, /* input buffer */
fixed bin(31) byaddr , /* input buffer length */
pointer byaddr , /* pointer to return_data */
fixed bin (31) byaddr , /* return code */
fixed bin (31) byaddr /* reason cide */
)
options (asm , inter, retcode ) /*
returns ( fixed bin(31) byvalue) */ ;

dcl
gxl1ini entry(
pointer byvalue, /* parse instance memory area (pima) */
fixed bin(31) byaddr, /* pima length */
fixed bin(31) byaddr, /* ccsid of document */
fixed bin(31) byaddr, /* parse feature flags*/
pointer byaddr, /* vector of system service routines */
pointer byaddr, /* system service routine parameter */
fixed bin(31) byaddr, /* return code */
fixed bin(31) byaddr /* reason code */
)
limited

Appendix B. Program source files 167


based( ptradd(csrt(19),16) )
returns( fixed bin(31) byvalue);

dcl
gxl1prs entry(
pointer byvalue, /* parse instance memory area (pima) */
fixed bin(31) byaddr, /* options flags */
pointer byaddr, /* xml document address */
fixed bin(31) byaddr, /* xml document length left (bytes) */
pointer byaddr, /* output buffer address */
fixed bin(31) byaddr, /* output buffer length left (bytes) */
fixed bin(31) byaddr, /* return code */
fixed bin(31) byaddr /* reason code */
)
limited
based( ptradd(csrt(19),20) )
returns( fixed bin(31) byvalue );

dcl
gxl1trm entry(
pointer byvalue, /* parse instance memory area (pima) */
fixed bin(31) byaddr, /* return code */
fixed bin(31) byaddr /* reason code */
)
limited
based( ptradd(csrt(19),24) )
returns( fixed bin(31) byvalue );

dcl
gxl_feat_strip_comments fixed bin(31)
value('80000000'xn),
gxl_feat_tokenize_whitespace fixed bin(31)
value('40000000'xn),
gxl_feat_cdata_as_chardata fixed bin(31)
value('20000000'xn);

define ordinal gxl_record_type (


gxl_rt_buffer_info value( '0f00f'xn ),
gxl_rt_xml_decl value( '0f01f'xn ),
gxl_rt_start_elem value( '0f02f'xn ),
gxl_rt_end_elem value( '0f03f'xn ),
gxl_rt_attr_name value( '0f04f'xn ),
gxl_rt_attr_value value( '0f05f'xn ),
gxl_rt_ns_decl value( '0f06f'xn ),
gxl_rt_char_data value( '0f07f'xn ),
gxl_rt_start_cdata value( '0f08f'xn ),
gxl_rt_end_cdata value( '0f09f'xn ),
gxl_rt_whitespace value( '0f0af'xn ),
gxl_rt_pi value( '0f0bf'xn ),
gxl_rt_comment value( '0f0cf'xn ),
gxl_rt_dtd_data value( '0f0df'xn ),
gxl_rt_unresolved_ref value( '0f0ef'xn ),
gxl_rt_error value( '0feef'xn ) )
prec(16) unsigned;

168 XML Processing Options on z/OS


dcl
gxl_rsn_parm_encoding_spec_invalid fixed bin(16) unsigned
value('1201'xn),
gxl_rsn_buffer_inbuf_end fixed bin(16) unsigned
value('1301'xn),
gxl_rsn_buffer_outbuf_end fixed bin(16) unsigned
value('1303'xn),
gxl_rsn_buffer_inoutbuf_end fixed bin(16) unsigned
value('1304'xn);

dcl
gxl_rsn_mask fixed bin(31)
value('0000ffff'xn);

dcl
/* per xmlss, 128k minimum */
gxl_min_pima_size fixed bin(31) value(128*1024),
/* per xmlss, 128 byte minimum */
gxl_min_output_buffer_size fixed bin(31) value(128),
/* expansion factor input->output */
gxl_io_factor fixed bin(31) value(150),
/* minimum size for qxd */
gxl_min_qxdwork_size fixed bin (31) value('8000'xn)
;

dcl
1 gxl_bufrec based,
2 gxl_rechdr,
3 gxl_rectyp ordinal gxl_record_type,
3 gxl_recflg fixed bin(8) unsigned,
3 gxl_recrsd fixed bin(8) unsigned,
3 gxl_reclen fixed bin(31),
2 gexl_recfms union,
3 gxl_bufinf,
4 gxl_dsopts fixed bin(32) unsigned,
4 gxl_prstat fixed bin(16) unsigned,
4 gxl_resrvd fixed bin(16) unsigned,
4 gxl_bufusd fixed bin(64) unsigned,
4 gxl_bufrof fixed bin(64) unsigned,
3 gxl_errrec,
4 gxl_retcod fixed bin(32) unsigned,
4 gxl_rsncod fixed bin(32) unsigned,
3 gxl_lvpairs char(0);

dcl
1 gxl_lvdata based,
2 gxl_vallen fixed bin(31),
2 gxl_valchs char( 1 refer(gxl_vallen) );

/* end of gxl declares */

dcl rc fixed bin(31);


dcl return_code fixed bin(31);

Appendix B. Program source files 169


dcl reason_code fixed bin(31);

dcl pima_addr pointer;


dcl pima_len fixed bin(31);

dcl document_addr pointer;


dcl document_len fixed bin(31);
dcl buffer_addr pointer;
dcl buffer_len fixed bin(31);

dcl document_current_addr pointer;


dcl document_len_remaining fixed bin(31);
dcl buffer_current_addr pointer;
dcl buffer_len_remaining fixed bin(31);

dcl current_record pointer;


dcl bufptr pointer;
dcl lvaddr pointer;

dcl obsize fixed bin(31);


dcl ccsid fixed bin(31);
dcl features fixed bin(31);

dcl pima( gxl_min_pima_size ) char(1);


dcl qxdw( gxl_min_qxdwork_size/8 ) fixed bin(63); /* dw boundary */

/* this value is intentionally small to force buffer spills */


dcl mxmm_doc_len fixed bin(31) value(4000);

dcl xmlDocument char(16000) var;

/* declare some messages */


dcl gxl_msgs ('1300'xn:'1310'xn) char (87) varying init('undef');
gxl_msgs('1300'xn) = 'The input buffer size is too small' ;
gxl_msgs('1301'xn) = 'The end of the input buffer has been reached' ;
gxl_msgs('1302'xn) =
'The output buffer was too small to contain the next item' ;
gxl_msgs('1303'xn) =
'The end of the output buffer has been reached' ;
gxl_msgs('1304'xn) =
'The end of both buffers has been reached' ;
gxl_msgs('1305'xn) =
'Application exit unable to allocate memory' ;

pima_addr = addr(pima);
pima_len = stg(pima);

ccsid = 37;

/* reverse the order of the next 2 lines to have comments ignored */


features = gxl_feat_strip_comments;
features = 0;

170 XML Processing Options on z/OS


rc = gxl1ini( pima_addr, pima_len,
ccsid, features,
sysnull(), sysnull(),
return_code, reason_code );

if return_code ^= 0
| reason_code ^= 0 then
do;
put skip list( 'init failed!!!' );
put skip list( rc );
put skip list( return_code );
put skip list( reason_code );
call pliretc(16);
end;
else
do;
obsize
= max( gxl_min_output_buffer_size,
mxmm_doc_len * gxl_io_factor / 100 );

buffer_addr = alloc(obsize);
buffer_len = obsize;

call read_xml( xmldocument );

/* set doc fields for initial parse */


document_addr = addrdata(xmldocument);
document_len = length(xmldocument);

/* copy doc addr to mutable field */


document_current_addr = document_addr;

/* copy doc length to mutable field */


document_len_remaining = document_len;

do loop;

/* copy buffer addr to mutable field */


buffer_current_addr = buffer_addr;

/* copy buf length to mutable field */


buffer_len_remaining = buffer_len;

return_code = 0;
reason_code = 0;

/*
*/
put skip list( '<<<<before invoking the parser' );
put skip list( 'doclrem=' || document_len_remaining );
put list( 'docacur= ' || hex(document_current_addr) );
put skip list( 'buflrem=' || buffer_len_remaining );
put list( 'bufaddr= ' || hex(buffer_current_addr) );

/* invoke the parser proper... */

Appendix B. Program source files 171


rc = gxl1prs( pima_addr, 0,
document_current_addr, document_len_remaining,
buffer_current_addr, buffer_len_remaining,
return_code, reason_code );

put skip list( '>>>>After returnung from the parser' );


reason_code = iand( reason_code, gxl_rsn_mask );

put skip list( 'rc= ' || rc );


put list( ' return_code= ' || return_code );
put list( ' reason_code= ' || hex(reason_code) );
if rc = 4 then
put skip list( gxl_msgs(reason_code) );
put skip list( 'doclrem=' || document_len_remaining );
put list( ' docacur= ' || hex(document_current_addr) );
put skip list( heximage(document_current_addr,32,' ') );
put skip list( 'buflrem=' || buffer_len_remaining );
put list( 'bufaddr= ' || hex(buffer_current_addr) );
put skip list( heximage(buffer_addr,32,' ') );
put skip list( heximage(buffer_addr+32,32,' ') );

current_record = buffer_addr;
do while( current_record < buffer_current_addr );

bufptr = current_record;

put skip list( ordinalname(bufptr->gxl_rectyp) );

/*
put skip list( bufptr->gxl_reclen );
*/

select( bufptr->gxl_rectyp );
when( gxl_rt_buffer_info )
do;
put skip list( hex(bufptr->gxl_bufusd) );
put list( hex(bufptr->gxl_bufrof) );
end;
when( gxl_rt_xml_decl )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
put skip list( lvaddr->gxl_vallen );
put list( lvaddr->gxl_valchs );
lvaddr += stg(gxl_vallen) + lvaddr->gxl_vallen;
put skip list( lvaddr->gxl_vallen );
put list( lvaddr->gxl_valchs );
lvaddr += stg(gxl_vallen) + lvaddr->gxl_vallen;
put skip list( lvaddr->gxl_vallen );
put list( lvaddr->gxl_valchs );
end;
when( gxl_rt_start_elem )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
put list( lvaddr->gxl_vallen );

172 XML Processing Options on z/OS


put list( lvaddr->gxl_valchs );
end;
when( gxl_rt_end_elem )
;
when( gxl_rt_attr_name )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
put list( lvaddr->gxl_vallen );
put list( lvaddr->gxl_valchs );
end;
when( gxl_rt_attr_value )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
put list( lvaddr->gxl_vallen );
put list( lvaddr->gxl_valchs );
end;
when( gxl_rt_ns_decl )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
put list( lvaddr->gxl_vallen );
put list( lvaddr->gxl_valchs );
end;
when( gxl_rt_char_data )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
put list( lvaddr->gxl_vallen );
put list( lvaddr->gxl_valchs );
end;
when( gxl_rt_start_cdata )
do;
;
end;
when( gxl_rt_end_cdata )
do;
;
end;
when( gxl_rt_whitespace )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
put list( lvaddr->gxl_vallen );
put list( lvaddr->gxl_valchs );
end;
when( gxl_rt_pi )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
put skip list( lvaddr->gxl_vallen );
put list( lvaddr->gxl_valchs );
lvaddr += stg(gxl_vallen) + lvaddr->gxl_vallen;
put list( lvaddr->gxl_vallen );
put list( lvaddr->gxl_valchs );
end;
when( gxl_rt_comment )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
put skip list( lvaddr->gxl_vallen );

Appendix B. Program source files 173


put list( lvaddr->gxl_valchs );
end;
when( gxl_rt_dtd_data )
do;
lvaddr = addr(bufptr->gxl_lvpairs);
put skip list( lvaddr->gxl_vallen );
put list( lvaddr->gxl_valchs );
end;
when( gxl_rt_unresolved_ref )
;
when( gxl_rt_error )
do;
put skip list( bufptr->gxl_retcod );
put list( hex(bufptr->gxl_retcod) );
put list( bufptr->gxl_rsncod );
put list( hex(bufptr->gxl_rsncod) );
end;
end;

current_record += bufptr->gxl_reclen;
end;

if return_code = 4 then
select( reason_code );
when( gxl_rsn_buffer_inbuf_end
,gxl_rsn_buffer_inoutbuf_end )
do; /* 1301, 1304 */
call read_xml( xmldocument );

/* reset doc fields for further parse */


document_addr = addrdata(xmldocument);
document_len = length(xmldocument);

/* copy doc addr to mutable field */


document_current_addr = document_addr;

/* copy doc length to mutable field */


document_len_remaining = document_len;
if reason_code = '1301'xn then c_1301=c_1301+1 ; else
c_1304 = c_1304 + 1;
end;
when( gxl_rsn_buffer_outbuf_end ) do;
c_1303 = c_1303 + 1;
end ; /* 1303 */
otherwise
leave;
end;
else
leave;
end;

rc = gxl1trm( pima_addr,
return_code, reason_code );

/* print out some statistics */

174 XML Processing Options on z/OS


put skip edit ( 'size; reads; readed;') (a) ;
put edit ( 'c_1301; c_1303; c_1304;') (a);
put skip edit ( size, ';', reads, ';', readed,';')
( f(8), a, f(8), a, f(8), a ) ;
put edit (c_1301,';', c_1303,';', c_1304, ';')
( f(8), a, f(8), a, f(8), a ) ;
end;

read_xml: proc( xmldocument );

dcl xmldocument char(16000) var;


dcl record char(4100) var; /* max lrecl is 4096 */
dcl p_qxdanswer pointer ; /* ptr to qxd answer area */

put skip list ('read_xml entered ');

if (reads = 0) then do ;
open file (xmlin) input;
put skip list ('xmlin opened');
end ;

xmldocument = '' ; /* empty the string buffer */


do while ((length(xmldocument) < size) ) ;
read file (xmlin) into (record) ;
if EOF = 1 then leave ;
xmldocument = xmldocument || record || '' ;
end ; /* fill buffer */

readed = readed + length (xmldocument);


put skip list ('**** read_xml/reads ', reads, 'length(xmlDocument)=',
length(xmldocument), 'Readed=', readed );
reads += 1;

if ( reads = 1 ) then do ;
call gxl1qxd ( qxdw(1) ,
gxl_min_qxdwork_size,
addrdata(xmldocument) ,
length(xmldocument),
p_qxdanswer,
return_code,
reason_code ) ;
put skip list ('plretv() returns ', pliretv());
rc = pliretv() ;
if (return_code = 0) then do ;
reason_code = iand( reason_code, gxl_rsn_mask );
put skip list( 'rc= ' || rc );
put list( ' return_code= ' || return_code );
put list( ' reason_code= ' || hex(reason_code) );
put skip list( heximage(p_qxdanswer,32,' ') );
put skip list( heximage(p_qxdanswer+32,32,' ') );

end;
else do ;
put skip list ('gxl1qxd returns rc', return_code,
' rsn ', reason_code ) ;

Appendix B. Program source files 175


end ;
end ; /* gxl1qsd with reads = 1 */
end;

end;

B.3 C program to extract the StringIDTable


Example B-3 shows our C program that extracts the StringIDTable from an OSR built by
xsdosrg.

Example B-3 C program to extract the STringIDTable


/* DISCLAIMER */
/* This example has been set up to demonstrate some details on
the str handling. It has been developed to the extent we needed to
describe some details. Therefor it has been only limited error
detection, error handling or even error recovery.
*/
/* #pragma runopts(RPTOPTS(ON)) */
#pragma runopts(XPLINK(ON))

#include <gxlhosrg.h>
#include <gxlhxec.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <iconv.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>

int main ( int argc, char * argv[] )


{

void * oima_p;
unsigned long oima_l, n_strings, str_offset, strid, strid_l, strid_o;
char handler_parms[128];
char * osr_buf, * stepc, * strid_id ;
char b [256] ;
char * d , * c ;
int osrbuf_l, i;
GXLHXSTR * strIDTbl_p;
GXLHXSTR_TBLENTRY * stepp ;
int strIDTbl_l;
int osr_size, num;
int rc, rsn;
iconv_t cd ;
size_t ij, ik ;

176 XML Processing Options on z/OS


FILE * osrin ;

struct stat info;

if (argc < 2) {
printf("\n we need at least 1 parameter the osr\n");
exit(-1);
} /* check arg counter */

if (stat(argv[1], &info) != 0) {
perror("stat() error");
exit (-1) ;
} /* could not stat() */
else
{ puts("stat() returned the following information about ");
printf("\n%s\n",argv[1]);
printf("created: %s\n", ctime(&info.st_createtime));
printf(" uid: %d\n", (int) info.st_uid);
printf(" gid: %d\n", (int) info.st_gid);
osr_size = info.st_size ;
printf(" size: %d\n", (int) info.st_size);
} /* check for availability & size */
fprintf(stderr,"\nsizeof(GXLHXSTR) %d, sizeof(GXLHXSTR_TBLENTRY) %d",
sizeof(GXLHXSTR), sizeof(GXLHXSTR_TBLENTRY) );

if ((osr_buf = (char *) malloc (osr_size)) == 0 ) {


fprintf(stderr,"\nCould not allocate storage to hold OSR");
fprintf(stderr,"\nSize requested was %d\n", osr_size);
exit(-1);
}

/* read the osr, do it in one chunk */


if (( osrin = fopen(argv[1], "rb")) == NULL ) {
fprintf(stderr,"\nfopen() failure\n");
exit (-1) ;
}
else { /* fopen() well done */
num = fread(osr_buf, sizeof( char ), osr_size , osrin );
if (num == osr_size ) {
/* fread success */
fprintf (stderr, "\nNumber of characters read = %i\n", num) ;
fclose( osrin ); }
else { /* fread failed */
if ( ferror(osrin) ) /* possibility 1 */ {
fprintf(stderr, "Error reading %s", argv[1] );
exit (-1) ;
}
else if ( feof(osrin)) { /* possibility 2 */
fprintf (stderr, "Prematurely found EOF\n" );
fprintf (stderr, "Number of characters read %d\n", num );
exit (-1) ;
}
} /* fread failue */
} /* end getting the osr into storage */

Appendix B. Program source files 177


/* Alloc the OIMA */
if ((oima_p = (void *) malloc(GXLHXEC_MIN_OIMA_SIZE)) == NULL)
{
fprintf(stderr,"\nCould not allocate the OIMA %d\n",
GXLHXEC_MIN_OIMA_SIZE) ;
exit (-1) ;
}

/* oima malloc succeeded */


oima_l = GXLHXEC_MIN_OIMA_SIZE;

/* Do the init OSRG call */


gxluInitOSRG(oima_p, oima_l, 0, (void *)handler_parms, &rc, &rsn);
if (rc != 0) {
fprintf(stderr,"\ngxluLoadOSR could not load OSR\n");
fprintf(stderr,"\nrc=%08x rsn=%08x\n", rc, rsn);
exit (-1) ;
}

/* Load the OSR to operate on. */

if ((oima_p > (void *) NULL) && (rc == GXLHXRC_SUCCESS))


{ /* generator initialized */

osrbuf_l = osr_size ;
gxluLoadOSR (oima_p, (void *)osr_buf, osrbuf_l, &rc, &rsn);
if (rc == GXLHXRC_SUCCESS) { /* OSR load succeeded */

/* Generate the strIDTabl */

strIDTbl_l = gxluGenStrIDTable
(oima_p, &strIDTbl_p, &rc, &rsn);

fprintf(stderr,"\ngxluStrIDtable returns with\n");


fprintf(stderr,"\nrc=%08x rsn=%08x\n", rc, rsn);
fprintf(stderr,"\nstrIDTbl_l =%08x\n", strIDTbl_l);

if (strIDTbl_l > 0) { /* strID table generated */


/* prepare for the conversion */
if ((cd = iconv_open("IBM-1047","UTF-8")) == (iconv_t)(-1)) {
fprintf(stderr, "Cannot open converter from %s to %sn",
"IBM-1047", "IBM-037");
cd = 0 ;
}
/* print header information */
fprintf(stderr,"\n strIDTbl_p at %08x\n ", strIDTbl_p);
/* the number of strings */
n_strings = strIDTbl_p -> XSTR_TBL_NUMSTR ;
fprintf(stderr,"\nXSTR_TBL_NUMSTR %08x\n ", n_strings );
/* Buffer offset */
str_offset = strIDTbl_p -> XSTR_TBL_STRBUFFOFFSET ;
/* strings are coded in the same cp as xsd */
fprintf(stderr,"\nXSTR_TBL_STRBUFFOFFSET %08x\n",
str_offset );
/****************************************************/

178 XML Processing Options on z/OS


/* step through entries */
stepp = & strIDTbl_p -> XSTR_TBLENTRY[0] ;
stepc = (char *) strIDTbl_p + str_offset ;
/*****/
/* string ID */
i = 0 ;
while (i < 99 ) { ;
fprintf(stderr,"\nstepp at %08X ", stepp );
strid = stepp -> XSTR_TBLENTRY_STRID ;
fprintf(stderr,"\nXSTR_TBLENTRY_STRID %08x ", strid);
strid_l = stepp -> XSTR_TBLENTRY_STRLEN ;
fprintf(stderr,"_STRLEN %08X ", strid_l);
strid_o = stepp -> XSTR_TBLENTRY_OFFSET ;
fprintf(stderr,"_OFFSET %08X \n", strid_o);
strid_id = stepc+strid_o ;
/* fprintf(stderr,"\nstring %24s",strid_id ); */
ij = strid_l ;
if (ij > 24 ) ij = 24 ; /* limit for our purposes */
ik = 256 ;
c = strid_id ; /* variable in buffer for iconv() */
d = (char *) b ;
rc = iconv(cd, &c, &ij, &d, &ik );
b[strid_l] = '\0' ;
fprintf(stderr,"\nstring %24s",b );
stepp = stepp++;
i++ ;
} /* while loop */
fprintf(stderr,"\nGame over \n");
}
/* strID table generated */

} /* OSR load succeeded */


else {
fprintf(stderr,"\ngxluLoadOSR could not load OSR\n");
fprintf(stderr,"\nrc=%08x rsn=%08x\n", rc, rsn);
exit (-1) ;
} /* handle error from LoadOSR */

} /* generator initialized */

} /* end of main() */

Appendix B. Program source files 179


B.4 Enterprise COBOL program to query XML document
declaration
Example B-4 shows an enterprise COBOL program invoking the GXL1QXD service. To run
this program, ensure that SYS1.CSSLIB is made available.

For the sake of simplicity, this program was written for a small XML document, so the entire
document was read into a working storage variable.

Example B-4 Enterprise COBOL program to call GXL1QXD program


Identification Division .
Program-ID QRYXML1 .
*Program Story
*
*Calling the z/OS XML System Services from COBOL.
*
*This program will call GXL1QXD service to query the XML document
*to get details from the XML prolog.
*
Environment Division .
*
Input-Output Section .
File-Control .
Select TstXML assign to TSTXML
Organization is line sequential .
*
Data Division .
File Section .
FD TstXML
Recording is V
Record is varying in size
depending on XML-Doc-Len .
01 Filler Pic X(500) .
*
Working-Storage Section .
* 01 level is aligned on doubleword boundary.
01 QXD-Input.
03 QXD-Input-Structure.
* Minimum size of input work area. See GXLYXEC for constants.
05 QXD-Input-WorkArea Pic X(32768) .
05 QXD-Input-WorkArea-Length Pic S9(09) Binary .
* Safe estimate for our example XML document.
05 QXD-Input-Buffer Pic X(300) .
05 QXD-Input-Buffer-Length Pic S9(09) Binary .
05 QXD-Output-Pointer Usage is Pointer .
05 QXD-Return-Code Pic S9(09) Binary .
* Upper half-word is for IBM service. Lower holds reason code.
05 QXD-Reason-Code Pic S9(09) Binary .
*
01 QXD-Return-Codes .
05 QXD-RetCode Pic S9(09) Binary .
88 QXD-Success Value 0 .
* Formatting the data returned from the service.
01 QXD-Output-Display .
05 QXD-Version Pic ZZZZ9 .

180 XML Processing Options on z/OS


05 QXD-XML-Autodet-Value Pic ZZZZ9 .
05 QXD-XML-Autodet-CCSID Pic ZZZZ9 .
05 QXD-XML-Version Pic ZZZZ9 .
05 QXD-XML-Release Pic ZZZZ9 .
05 QXD-XML-Spec-CCSID Pic ZZZZ9 .
05 QXD-XML-Flag1 Pic X .
05 QXD-XML-Flag2 Pic X .
05 QXD-Reserved Pic ZZZZ9 .
05 QXD-XML-Decl-Length Pic ZZZZ9 .
*
01 XML-Doc-Len Pic 9(04) .
*
01 WS-Misc.
05 rc Pic S9(09) Binary value 0 .
05 Read-Buffer Pic X(500) Value spaces .
05 Length-pointer Pic S9(09) Binary value 1 .
05 XMLSS-PGM Pic X(8) Value "GXL1QXD" .
05 End-of-File Pic X Value space .
*
Linkage Section .
01 QXD-Output-Structure .
Copy GXLYQXD .
*
Procedure Division .
* Some house-keeping.
Move Low-Values to QXD-Input-WorkArea
Move 32768 to QXD-Input-WorkArea-Length
Move 0 to QXD-Return-Code QXD-Reason-Code .
Initialize QXD-Output-Display
Open input TstXML .
* Read the document into the buffer completely while summing
* the length of buffer .
Perform Read-XML-Doc thru Read-Exit .
Perform String-XML-data
thru String-Exit
until End-of-File = "Y"
.
* Show the length of the document read .
Display "Buffer Length : " QXD-Input-Buffer-Length
.
* And, off we go
Call XMLSS-PGM using
QXD-Input-WorkArea
QXD-Input-WorkArea-Length
QXD-Input-Buffer
QXD-Input-Buffer-Length
QXD-Output-Pointer
QXD-Return-Code
QXD-Reason-Code
returning rc
.
* Crash and burn if rc is not good.
If rc > 0
Display "Return Code : " QXD-Return-Code
Display "Reason Code : " QXD-Reason-Code
Go to Abort-Run

Appendix B. Program source files 181


End-If .
* No, we are good, start reporting.
Evaluate QXD-Return-Code
When 0
Set address of QXD-Output-Structure to QXD-Output-Pointer
Move corresponding
QXD-Return-Structure to QXD-Output-Display
*
Display "QXD Version : "
QXD-Version of QXD-Output-Display
Display "XML Autodet Value : "
QXD-XML-Autodet-Value of QXD-Output-Display
Display "XML Autodet CCSID : "
QXD-XML-Autodet-CCSID of QXD-Output-Display
Display "XML Version : "
QXD-XML-Version of QXD-Output-Display
Display "XML Release : "
QXD-XML-Release of QXD-Output-Display
Display "XML Spec CCSID : "
QXD-XML-Spec-CCSID of QXD-Output-Display
Display "XML Flags 1 : "
QXD-XML-Flag1 of QXD-Output-Display
Display "XML Flags 2 : "
QXD-XML-Flag2 of QXD-Output-Display
Display "XML Reserved : "
QXD-Reserved of QXD-Output-Display
Display "XML Decl Length : "
QXD-XML-Decl-Length of QXD-Output-Display
End-Evaluate
.
*
Close TstXML .
* Three-point landing
Abort-Run .
Stop Run .
*
Read-XML-Doc .
Read TstXML into Read-Buffer
at end
Move "Y" to End-of-File

End-Read .
Read-Exit .
Exit .
*
String-XML-data .
Add XML-Doc-Len to QXD-Input-Buffer-Length
String Read-Buffer (1:XML-Doc-Len) delimited by size
into QXD-Input-Buffer
with pointer Length-pointer .

Perform Read-XML-Doc
thru Read-Exit .
String-Exit .
Exit .

182 XML Processing Options on z/OS


B.5 C program to query XML document declaration
For completeness we have implemented a small C program that is similar to the enterprise
COBOL shown in Appendix B.4, “Enterprise COBOL program to query XML document
declaration” on page 180. It can be compiled and installed in the z/OS UNIX environment. As
in the previous example, it displays major information about the detected code page of the
document. The output is condensed.

Example B-5 Querying the sample


HDM @ SC80:/u/hdm/sg7810>qxd za*
stat() returned the following information about

zample-utf8.xml
created: Mon Aug 31 09:21:47 2009

uid: 58
gid: 0
size: 254

Prematurely found EOF


Number of characters read 254

QXD_Version 1x( 1)
QXD_XML_Autodet_value 7x( 7)
QXD_XML_Autodet_CCSID 4B8x( 1208)
QXD_XML_Specified_CCSID 4B8x( 1208)
QXD_XML_Decl_Len 3Ax( 58)
QXD_XML_Version 1x( 1)
QXD_XML_Release 0x( 0)
QXD_XML_Flag1 C0x( 192)
QXD_XML_Flag2 E0x( 224)
HDM @ SC80:/u/hdm/sg7810>

Example B-6 C program to extract basic XML document information


/* DISCLAIMER */
/* This example has been set up to demonstrate some details on
the str handling. It has been developed to the extent we needed to
describe some details. Therefor it has been only limited error
detection, error handling or even error recovery.
*/

/* command to get this running


c89 -o qxd -Wc,dll qxd.c /usr/lib/gxlxxml1.x /usr/lib/gxlxosr1.x
*/

/* #pragma runopts(RPTOPTS(ON)) */
#pragma runopts(XPLINK(ON))

#include <gxlhosrg.h>
#include <gxlhxec.h>
#include <gxlhqxd.h>
#include <stdlib.h>
#include <stdio.h>

Appendix B. Program source files 183


#include <string.h>

#include <iconv.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>

int main ( int argc, char * argv[] )


{

void * oima_p;
unsigned long oima_l, n_strings, str_offset, strid, strid_l, strid_o;
char handler_parms[128];
char * xml_buf, * stepc, * strid_id ;
int xmlbuf_l, i;
long work_area_length = GXLHXEC_MIN_QXDWORK_SIZE;
long work_area[((GXLHXEC_MIN_QXDWORK_SIZE)+7)/4];
GXLHQXD * rt_d ;
int xml_size, num;
int rc, rsn;
size_t ij, ik ;

FILE * xmlin ;

struct stat info;

if (argc < 2) {
printf("\n we need at least 1 parameter the XML doc name\n");
exit(-1);
} /* check arg counter */

if (stat(argv[1], &info) != 0) {
perror("stat() error");
exit (-1) ;
} /* could not stat() */
else
{ puts("stat() returned the following information about ");
printf("\n%s\n",argv[1]);
printf("created: %s\n", ctime(&info.st_createtime));
printf(" uid: %d\n", (int) info.st_uid);
printf(" gid: %d\n", (int) info.st_gid);
printf(" size: %d\n", (int) info.st_size);
} /* check for availability & size */

xml_size = 1024 ; /* assume 1K at themoment */


if ((xml_buf = (char *) malloc (xml_size)) == 0 ) {
fprintf(stderr,"\nCould not allocate storage to hold xml");
fprintf(stderr,"\nSize requested was %d\n", xml_size);
exit(-1);
}

/* Open the File to read the XML from */


if (( xmlin = fopen(argv[1], "rb")) == NULL ) {

184 XML Processing Options on z/OS


fprintf(stderr,"\nfopen() failure\n");
exit (-1) ;
}
else { /* fopen() well done */
/* We try to read xml_size or until EOF occurs. */
num = fread(xml_buf, sizeof( char ), xml_size , xmlin );
if (num == xml_size ) {
/* fread success */
fprintf (stderr, "\nNumber of characters read = %i\n", num) ;
fclose( xmlin ); }
else { /* fread failed */
if ( ferror(xmlin) ) /* possibility 1 */ {
fprintf(stderr, "Error reading %s", argv[1] );
exit (-1) ;
}
else if ( feof(xmlin)) { /* possibility 2 */
fprintf (stderr, "Prematurely found EOF\n" );
fprintf (stderr, "Number of characters read %d\n", num );
xml_size = num ; /* try this length */
/* exit (-1) ; may be allowed here */
}
} /* fread failue */
} /* end getting the xml into storage */
/* now we are ready to go for calling qxd */

gxlpQuery ( work_area,
work_area_length ,
(char *)(xml_buf) ,
xml_size ,
&rt_d,
&rc,
&rsn ) ;
if (rc > 0 ) {
fprintf(stderr,
"\ngxlpQuery returned rc=%6d(%8X) rsn=%6d(%8X)\n", rc, rsn);
}
/*
int QXD_Version;
unsigned int QXD_XML_Autodet_value;
unsigned int QXD_XML_Autodet_CCSID;
unsigned short QXD_XML_Version;
unsigned short QXD_XML_Release;
unsigned int QXD_XML_Specified_CCSID;
/*****************************************************************/
/* QXD Flag1 */
/* - standalone bit is on if standalone = yes */
/* - bom is on if byte order mark detected in the doc */
/* - encoding undetected bit is on if encoding not auto-detected */
/*****************************************************************/
/* unsigned char QXD_XML_Flag1 */
else {
fprintf(stderr,
"\nQXD_Version %8Xx(%8d) ",
rt_d->QXD_Version , rt_d->QXD_Version );
fprintf(stderr,

Appendix B. Program source files 185


"\nQXD_XML_Autodet_value %8Xx(%8d) ",
rt_d->QXD_XML_Autodet_value, rt_d->QXD_XML_Autodet_value );
fprintf(stderr,
"\nQXD_XML_Autodet_CCSID %8Xx(%8d)",
rt_d->QXD_XML_Autodet_CCSID, rt_d->QXD_XML_Autodet_CCSID );
fprintf(stderr,
"\nQXD_XML_Specified_CCSID %8Xx(%8d)",
rt_d->QXD_XML_Specified_CCSID, rt_d->QXD_XML_Specified_CCSID );
fprintf(stderr,
"\nQXD_XML_Decl_Len %8Xx(%8d)",
rt_d->QXD_XML_Decl_Len , rt_d->QXD_XML_Decl_Len );
fprintf(stderr,
"\nQXD_XML_Version %8Xx(%8d)",
rt_d->QXD_XML_Version , rt_d->QXD_XML_Version );
fprintf(stderr,
"\nQXD_XML_Release %8Xx(%8d)",
rt_d->QXD_XML_Release , rt_d->QXD_XML_Release );
fprintf(stderr,
"\nQXD_XML_Flag1 %8Xx(%8d)",
rt_d->QXD_XML_Flag1 , rt_d->QXD_XML_Flag1 );
fprintf(stderr,
"\nQXD_XML_Flag2 %8Xx(%8d)",
rt_d->QXD_XML_Flag2 , rt_d->QXD_XML_Flag2 );
}
fprintf(stderr, "\n") ;

} /* end of main() */

B.6 Enterprise COBOL program to invoke z/OS XML System


Services parser without validation
Example B-7 on page 187 takes an arbitrarily sized XML document and parses it to output the
tokens (start tags, attribute names, and so forth) and their values. This program shows the
handling of reason codes x'1301', x'1303' and x'1304' to handle cases of buffer overrun. This
program does not handle all possible reason codes with parsing return code greater than
zero. Thus, the reason code x’1302’ with parsing return code of 8 is not handled. Also, not all
the token types possible in an XML document have been handled here.

For documents with encoding values other than EBCDIC, the COBOL functions
NATIONAL-OF and DISPLAY-OF have been used to output data in EBCDIC format. This
program accepts the encoding of the document through job step PARM parameter. It is a four
digit value to be padded with leading zeroes for the CCSID of the document. If this parameter
is omitted, the program passes 1208 (UTF-8) as the default CCSID. This program was tested
with the XML document to be parsed passed as a HFS file and referred in this program with
the DD name TSTXML. The output of the program is also an HFS file and is referred in this
program with the DD name OUTDATA.

186 XML Processing Options on z/OS


Notes:
򐂰 The feature flag XEC-Feat-Full-End is supported only in v10 onwards. If this flag is to
be used, then uncomment the line for adding this feature flag in 1200-Init-XMLSS
paragraph. Also, uncomment all the lines in 2123-XML-End-Element paragraph.
򐂰 If not using XEC-Feat-Full-End support, then leave the comments mentioned above as
is.
򐂰 In 2126-XML-Char-Data paragraph, the comment for writing to output file could be
removed if it is ensured that the output file is sufficiently large to accommodate the
character data in the XML document.

Example B-7 COBOL program calling z/OS XML System Services on z/OS for parsing
Identification Division .
Program-ID XMLPRS1 .
*
*This is a sample program to invoke z/OS XML System Services
*to a parse an XML document without validation.
*
*This program will read from file as many times as required to
*fill the Input-Buffer to be sent to the z/OS XML parser. The
*size of this buffer has been set in this program to be 4KB.
*
*The output buffer has been set to 4KB for the sample XML document
*taken for this program. This size of the buffer ensured that, we
*do not hit x'1302' but we do encounter x'1303' or x'1304' reason
*codes.
*
*In practice though, an estimate of output buffer being twice the
*size of input buffer is good.
*
*
* Return Code Reason Code Short Description
* ----------- ----------- -----------------
* 4 1301 Input Buffer ended
* 8 1302 Output Buffer small
* 4 1303 Output Buffer ended
* 4 1304 Input and Output Buffer end
*
*Handles encoding : UTF-16BE (1200), UTF-8 (1208) and
* EBCDIC encodings. Default : 1208
*
*See SYS1.MACLIB(GXL*) for data structures and constant declar-
*ations.
*
*aanemali.
*
Environment Division .
*
Input-Output Section .
File-Control .
Select TstXML assign to TSTXML
Organization is line sequential .
*

Appendix B. Program source files 187


Select OutData assign to OUTDATA
Organization is line sequential .
*
Data Division .
File Section .
FD TstXML
Recording is V
Record is varying in size
depending on XML-Doc-Len .
01 TsTXML-Rec Pic X(1024) .
*
FD OutData
Recording is V
Record contains 5120 characters .
01 OutData-Rec Pic X(5120) .
*
Working-Storage Section .
01 Service-Constants .
03 Args.
05 XEC-Min-PIMA Pic 9(09) Comp-5
Value 131072 .
05 XEC-NVParse-Min-PIMA Pic 9(09) Comp-5
Value 131072 .
05 XEC-VParse-Min-PIMA Pic 9(09) Comp-5
Value 786432 .
05 XEC-Feat-Strip-Cmnts Pic 9(09) Comp-5
Value 2147483648 .
05 XEC-Feat-Full-End Pic 9(09) Comp-5
Value 16777216 .
05 XEC-Enc-UTF-8 Pic 9(09) Comp-5
Value 1208 .
03 Record-Type .
05 Parsed-Stream-RecType Pic XX .
88 Buffer-Info-Rec Value X"F00F" .
88 XML-Declaration Value X"F01F" .
88 XML-Start-Element Value X"F02F" .
88 XML-End-Element Value X"F03F" .
88 XML-Attribute-Name Value X"F04F" .
88 XML-Attribute-Value Value X"F05F" .
88 XML-Namespace-Decl Value X"F06F" .
88 XML-Character-Data Value X"F07F" .
88 XML-Start-CDATA Value X"F08F" .
88 XML-End-CDATA Value X"F09F" .
88 XML-Whitespace Value X"F0AF" .
88 XML-PI Value X"F0BF" .
88 XML-Comment Value X"F0CF" .
88 XML-DTD-Data Value X"F0DF" .
88 XML-Unresolved-Ref Value X"F0EF" .
88 XML-Aux-Info Value X"F0FF" .
88 Error-Info-Rec Value X"FEEF" .
*GXL1INI structure .
01 GXL1INI-Structure .
05 GXL1INI-PIMA Pic X(131072) .
05 GXL1INI-PIMA-Length Pic 9(09) Comp-5 .
05 GXL1INI-CCSID Pic 9(09) Comp-5 .

188 XML Processing Options on z/OS


05 GXL1INI-Flags Pic 9(09) Comp-5 .
05 GXL1INI-Sys-Svc-Struct Usage is Pointer .
05 GXL1INI-Sys-Svc-Parm Usage is Pointer .
05 GXL1INI-Return-Code Pic 9(09) Comp-5 .
05 GXL1INI-Reason-Code Pic 9(09) Comp-5 .
*GXL1PRS structure. PIMA to be provided from elsewhere.
01 GXL1PRS-Structure .
05 GXL1PRS-Options Pic 9(09) Comp-5 .
05 GXL1PRS-Input-Buff-Address Usage pointer .
05 GXL1PRS-Input-Buff-Bytes Pic 9(09) Comp-5 .
05 GXL1PRS-Output-Buff-Address Usage pointer .
05 GXL1PRS-Output-Buff-Bytes Pic 9(09) Comp-5 .
05 GXL1PRS-Return-Code Pic 9(09) Comp-5 .
05 GXL1PRS-Reason-Code Pic 9(09) Comp-5 .
*
01 GXL-Service-Return-Codes.
05 GXL-Return-Codes Pic 9(09) Comp-5 .
05 GXL-Return-Codes-R Redefines GXL-Return-Codes.
10 GXL-Hex-Return-Code Pic X(04) .
88 XRC-Success Value X"00000000" .
88 XRC-Warning Value X"00000004" .
88 XRC-Failure Value X"00000008" .
88 XRC-Not-Well-Formed Value X"0000000C" .
88 XRC-Fatal Value X"00000010" .
88 XRC-Load-Failed Value X"00000014" .
88 XRC-Not-Valid Value X"00000018" .
05 GXL1TRM-Return-Code Pic 9(09) Comp-5 .
05 GXL1TRM-Reason-Code Pic 9(09) Comp-5 .
*
01 GXL-Service-Reason-Codes.
05 GXL1PRS-Reason-Codes Pic 9(09) Comp-5 .
05 GXL1PRS-Reason-Codes-R Redefines GXL1PRS-Reason-Codes .
10 Filler Pic X(02) .
10 GXL1PRS-Hex-Rsn-Code Pic X(02) .
88 GXL1PRS-InBuff-End Value X"1301" .
88 GXL1PRS-OutBuf-Small Value X"1302" .
88 GXL1PRS-OutBuf-End Value X"1303" .
88 GXL1PRS-InOutBuf-Ended Value X"1304" .
*
01 Output-Buffer-Common-Header .
05 OP-Buff-Rec-Type Pic XX Value Spaces .
05 OP-Buff-Rec-Flags Pic X Value Spaces .
05 Filler Pic X Value Spaces .
05 OP-Buff-Rec-Length Pic 9(09) Comp-5 Value 0 .
*
01 Buffer-Info-Record .
05 BI-DataStream-Opts Pic 9(09) Comp-5 Value 0 .
05 BI-Parse-Status Pic 9(04) Comp-5 Value 0 .
05 Filler Pic 9(04) Comp-5 Value 0 .
05 BI-Buff-Length-Used Pic 9(18) Comp-5 Value 0 .
05 BI-Error-Offset Pic 9(18) Comp-5 Value 0 .
*
01 XMLSS-Programs .
05 XMLSS-GXL1INI Pic X(08) Value "GXL1INI" .
05 XMLSS-GXL1PRS Pic X(08) Value "GXL1PRS" .

Appendix B. Program source files 189


05 XMLSS-GXL1TRM Pic X(08) Value "GXL1TRM" .
*
01 XML-Doc-Len Pic 9(09) .
*
01 Misc .
03 All-Flags.
05 GXL1INI-Called Pic X Value spaces.
05 Scan-End Pic X Value spaces.
05 Buffer-Limit-Exceeded Pic X Value "N" .
05 Buffer-Limit-Reached Pic X Value "N" .
05 End-of-File Pic X Value "N" .
05 Adjusted-Buffer Pic X Value "N" .
05 Parsing-Completed Pic X Value spaces.
05 Hard-Error Pic X Value spaces.
03 Other-Items .
05 1KB Pic 9(9) Comp-5 Value 1024.
05 Buffer-Limit Pic 9(9) Comp-5 Value 4096.
05 Call-Return-Code Pic 9(9) Comp-5 Value 0.
05 Length-pointer Pic 9(9) Comp-5 value 1.
03 Display-Items .
05 Parse-Return-Code-X Pic X(04) .
05 Parse-Return-Code-R redefines Parse-Return-Code-X .
10 Parse-Return-Code-B Pic 9(9) Comp-5 .
05 Parse-Reason-Code-X Pic X(04) .
05 Parse-Reason-Code-R redefines Parse-Reason-Code-X .
10 Parse-Reason-Code-B Pic 9(9) Comp-5 .
05 Error-Offset-X Pic X(08) .
05 Error-Offset-R redefines Error-Offset-X .
10 Filler Pic X(04) .
10 Error-Offset-B Pic 9(09) Comp-5 .
*
01 IO-Vars .
03 Current-IO .
05 Read-Buffer Pic X(1024) Value spaces .
05 Write-Buffer Pic X(5120) Value spaces .
05 Write-Buffer-R Redefines Write-Buffer .
10 Write-Buffer-N Pic N(2560) .
05 Input-Buffer Pic X(4096) Value spaces .
05 Input-Buffer-Length Pic 9(09) Comp-5 Value 0 .
05 Output-Buffer Pic X(5120) Value spaces.
05 Output-Buffer-N Pic N(2560)
usage national Value spaces.
05 OP-Buffer-Start Pic 9(09) Comp-5 Value 0 .
05 OP-Buffer-Length Pic 9(09) Comp-5 Value 0 .
03 Prev-IO .
05 Read-Buffer-Prev Pic X(1024) Value spaces .
05 Read-Buffer-Len-Prev Pic 9(09) Comp-5 Value 0 .
*
01 WS-Work.
05 Leader-String Pic X(30) Value spaces.
05 Length-String Pic X(4) Value spaces .
05 Length-String-R Redefines Length-String .
10 Length-Binary Pic 9(09) Comp-5 .
05 Test-Reason-Code Pic 9(09) Comp-5 .
05 Test-Reason-Code-R redefines Test-Reason-Code .

190 XML Processing Options on z/OS


10 Filler Pic 9(04) Comp-5 .
10 XMLSS-Reason-Code Pic 9(04) Comp-5 .
05 Parm-CCSID Pic X(04) .
05 Parm-CCSID-R redefines Parm-CCSID .
10 Parm-CCSID-Num Pic 9(04) .
*
01 Messages .
05 Message-String Pic X(100) Value spaces .
05 Svc-Return-Code Pic ZZZ9 .
05 Svc-Reason-Code-FW Pic 9(09) Comp-5 .
05 Svc-Reason-Code-R Redefines Svc-Reason-Code-FW .
10 Filler Pic XX .
10 Svc-Reason-Code-B Pic 9(4) Comp-5 .
05 Svc-Reason-Code Pic ZZZ9 .
05 FW-To-Edited Pic ZZZZZZ9 .
05 String-1 Pic X(30) .
*
Linkage Section .
01 Step-Parm .
02 Parm-Length Pic 9(04) Comp-5 .
02 Parm-CCSID-L Pic X(04) .
*
Procedure Division using Step-Parm .
Perform 1000-Hskp thru 1000-Exit
Perform 2000-Do-Parse thru 2000-Exit
until Parsing-Completed = "Y"
or Hard-Error = "Y"
Perform 8000-Done thru 8000-Exit
.
Stop run .
*
1000-Hskp .
Open input TstXML
output OutData
.
Perform 1100-Read-Doc-Into-Buffer
thru 1100-Exit
until End-Of-File = "Y"
or Buffer-Limit-Reached = "Y"
or Buffer-Limit-Exceeded = "Y"
.
If End-of-File = "Y"
and Input-Buffer-Length = 0
Move "Y" to Hard-Error
Else
Perform 1200-Init-XMLSS thru 1200-Exit
End-If
.
1000-Exit .
Exit .

1100-Read-Doc-Into-Buffer .
Perform 9000-Read-File thru 9000-Exit
If End-Of-File = "Y"
Go to 1100-Exit

Appendix B. Program source files 191


End-If
.
Add XML-Doc-Len to Input-Buffer-Length
If Input-Buffer-Length < Buffer-Limit
String Read-Buffer (1:XML-Doc-Len) delimited by size
into Input-Buffer
with pointer Length-pointer
End-String
End-If
.
If Input-Buffer-Length = Buffer-Limit
String Read-Buffer (1:XML-Doc-Len) delimited by size
into Input-Buffer
with pointer Length-pointer
End-String
Move "Y" to Buffer-Limit-Reached
End-If
.
If Input-Buffer-Length > Buffer-Limit
Subtract XML-Doc-Len from Input-Buffer-Length
Move XML-Doc-Len to Read-Buffer-Len-Prev
Move Read-Buffer (1:Read-Buffer-Len-Prev)
to Read-Buffer-Prev (1:Read-Buffer-Len-Prev)
Move "Y" to Buffer-Limit-Exceeded
End-If
.
1100-Exit .
Exit .

1200-Init-XMLSS .
Move spaces to GXL1INI-PIMA
Compute GXL1INI-PIMA-Length = XEC-NVParse-Min-PIMA
If Parm-Length = 0
Move XEC-ENC-UTF-8 to GXL1INI-CCSID
Else
Move Parm-CCSID-L to Parm-CCSID
Move Parm-CCSID-Num to GXL1INI-CCSID
End-If
Compute GXL1INI-Flags = XEC-Feat-Strip-Cmnts
*Uncomment below line if running on v10
* + XEC-Feat-Full-End
Move zero to GXL1INI-Return-Code
GXL1INI-Reason-Code
.
Call XMLSS-GXL1INI
using GXL1INI-PIMA
GXL1INI-PIMA-Length
GXL1INI-CCSID
GXL1INI-Flags
Omitted
Omitted
GXL1INI-Return-Code
GXL1INI-Reason-Code
.
If GXL1INI-Return-Code > 0

192 XML Processing Options on z/OS


Move GXL1INI-Return-Code to Svc-Return-Code
Move GXL1INI-Reason-Code to Svc-Reason-Code-FW
Move Svc-Reason-Code-B to Svc-Reason-Code
String "GXL1INI Return Code : " delimited by size
Svc-Return-Code delimited by size
" Reason Code : " delimited by size
Svc-Reason-Code delimited by size
into Message-String
Display Message-String
Move "Y" to Hard-Error
Else
Move "Y" to GXL1INI-Called
End-If
.
1200-Exit .
Exit .

2000-Do-Parse .
Initialize GXL1PRS-Structure
Set GXL1PRS-Input-Buff-Address to
address of Input-Buffer
Set GXL1PRS-Output-Buff-Address to
address of Output-Buffer
Move Input-Buffer-Length to GXL1PRS-Input-Buff-Bytes
Compute GXL1PRS-Output-Buff-Bytes = 5 * 1KB
.
Call XMLSS-GXL1PRS using
GXL1INI-PIMA
GXL1PRS-Options
GXL1PRS-Input-Buff-Address
GXL1PRS-Input-Buff-Bytes
GXL1PRS-Output-Buff-Address
GXL1PRS-Output-Buff-Bytes
GXL1PRS-Return-Code
GXL1PRS-Reason-Code
returning Call-Return-Code
.
Move spaces to Message-String
Move GXL1PRS-Return-Code to Svc-Return-Code
Move GXL1PRS-Reason-Code to Svc-Reason-Code-FW
Move Svc-Reason-Code-B to Svc-Reason-Code
Move Input-Buffer-Length to FW-To-Edited
String "Length Input Buffer : " delimited by size
FW-To-Edited delimited by size
" GXL1PRS Return Code : " delimited by size
Svc-Return-Code delimited by size
" Reason Code : " delimited by size
Svc-Reason-Code delimited by size
into Message-String
Display Message-String
.
Move GXL1PRS-Return-Code to GXL-Return-Codes
Evaluate true
When XRC-Success
Perform 2100-Process-Output thru 2100-Exit

Appendix B. Program source files 193


Move "Y" to Parsing-Completed
When XRC-Warning
Perform 2100-Process-Output thru 2100-Exit
Perform 2200-Handle-Warn-Reason-Code thru 2200-Exit
When XRC-Failure
Move spaces to Message-String
Move "Failure." to String-1
Move "Y" to Hard-Error
Perform 2100-Process-Output thru 2100-Exit
When XRC-Not-Well-Formed
Move spaces to Message-String
Move "Document not well formed." to String-1
Move "Y" to Hard-Error
Perform 2100-Process-Output thru 2100-Exit
When XRC-Fatal
Move spaces to Message-String
Move "Fatal Error." to String-1
Move "Y" to Hard-Error
Perform 2100-Process-Output thru 2100-Exit
When XRC-Load-Failed
Move spaces to Message-String
Move "Service not loaded." to String-1
Move "Y" to Hard-Error
Perform 2100-Process-Output thru 2100-Exit
When XRC-Not-Valid
Move spaces to Message-String
Move "Doc not valid as per schema." to String-1
Move "Y" to Hard-Error
Perform 2100-Process-Output thru 2100-Exit
End-Evaluate
.
If Hard-Error = "Y"
or Parsing-Completed = "Y"
Go to 2000-Exit
End-If
.
Evaluate End-Of-File
also Adjusted-Buffer
When "Y" also "Y"
Continue
When "Y" also "N"
Move "Y" to Parsing-Completed
When "N" also "Y"
Continue
When "N" also "N"
If Buffer-Limit-Exceeded = "Y"
Move Read-Buffer-Prev (1:Read-Buffer-Len-Prev)
to Input-Buffer (1:Read-Buffer-Len-Prev)
Move Read-Buffer-Len-Prev
to Input-Buffer-Length
Move "N" to Buffer-Limit-Exceeded
Move spaces to Read-Buffer-Prev
Move zero to Read-Buffer-Len-Prev
Else
Perform 1100-Read-Doc-Into-Buffer thru 1100-Exit

194 XML Processing Options on z/OS


until End-Of-File = "Y"
or Buffer-Limit-Reached = "Y"
or Buffer-Limit-Exceeded = "Y"
End-If
End-Evaluate

Move "N" to Adjusted-Buffer


.
2000-Exit .
Exit .

2100-Process-Output .
Move 1 to OP-Buffer-Start
Move 8 to OP-Buffer-Length
Move Output-Buffer (OP-Buffer-Start:OP-Buffer-Length)
to Output-Buffer-Common-Header
Compute OP-Buffer-Start = OP-Buffer-Length + 1
Compute OP-Buffer-Length = OP-Buff-Rec-Length - 8
Move Output-Buffer (OP-Buffer-Start:OP-Buffer-Length)
to Buffer-Info-Record
.
If BI-Error-Offset > 0
Move spaces to Message-String
Perform 2110-Get-Error-Record thru 2110-Exit
Go to 2100-Exit
End-If
.
Compute OP-Buffer-Start = OP-Buffer-Start +
OP-Buffer-Length
Compute OP-Buffer-Length = 0
.
Move space to Scan-End
Perform 2120-Scan-Output-Buffer thru 2120-Exit
until Scan-End = "Y"
.
2100-Exit .
Exit .

2110-Get-Error-Record .
Move Output-Buffer(BI-Error-Offset + 9 : 4)
to Parse-Return-Code-X
Move Output-Buffer(BI-Error-Offset + 13 : 4)
to Parse-Reason-Code-X
Move Output-Buffer(BI-Error-Offset + 17 : 8)
to Error-Offset-X
Move Error-Offset-B to FW-To-Edited
String "Error offset in doc : " delimited by size
FW-To-Edited delimited by size
into Message-String
Display Message-String
.
2110-Exit .
Exit .

2120-Scan-Output-Buffer .

Appendix B. Program source files 195


Move Output-Buffer (OP-Buffer-Start:2)
to Parsed-Stream-RecType
.
Evaluate true
When XML-Declaration
Perform 2121-XML-Declaration thru 2121-Exit
When XML-Start-Element
Perform 2122-XML-Start-Element thru 2122-Exit
When XML-End-Element
Perform 2123-XML-End-Element thru 2123-Exit
When XML-Attribute-Name
Perform 2124-XML-Attrib-Name thru 2124-Exit
When XML-Attribute-Value
Perform 2125-XML-Attrib-Value thru 2125-Exit
When XML-Character-Data
Perform 2126-XML-Char-Data thru 2126-Exit
When XML-Namespace-Decl
Perform 2127-XML-NS-Decl thru 2127-Exit
When other
Move spaces to Message-String
String "Rec Type : " delimited by size
Parsed-Stream-RecType delimited by size
" Not handled in this code. Aborting."
delimited by size
into Message-String
End-String
Display Message-String
Move "Y" to Scan-End Hard-Error
End-Evaluate
.
If OP-Buffer-Start >= BI-Buff-Length-Used
Move "Y" to Scan-End
End-If
.
2120-Exit .
Exit .

2121-XML-Declaration .
Move "XML Version : " to Leader-String
Perform 4000-Move-Pointer thru 4000-Exit
Perform 6000-Build-Output thru 6000-Exit
Perform 7000-Move-Ahead thru 7000-Exit
Perform 9100-Write-File thru 9100-Exit
.
Move "XML Encoding : " to Leader-String
Perform 5000-Move-Pointer-Next thru 5000-Exit
Perform 6000-Build-Output thru 6000-Exit
Perform 7000-Move-Ahead thru 7000-Exit
Perform 9100-Write-File thru 9100-Exit
.
Move "XML Standalone : " to Leader-String
Perform 5000-Move-Pointer-Next thru 5000-Exit
Perform 6000-Build-Output thru 6000-Exit
Perform 7000-Move-Ahead thru 7000-Exit
Perform 9100-Write-File thru 9100-Exit

196 XML Processing Options on z/OS


.
2121-Exit .
Exit .

2122-XML-Start-Element .
Move "Start Element name : " to Leader-String
Perform 4000-Move-Pointer thru 4000-Exit
Perform 6000-Build-Output thru 6000-Exit
Perform 7000-Move-Ahead thru 7000-Exit
Perform 9100-Write-File thru 9100-Exit
.
Move "Start Element namespace : " to Leader-String
Perform 5000-Move-Pointer-Next thru 5000-Exit
Perform 6000-Build-Output thru 6000-Exit
Perform 7000-Move-Ahead thru 7000-Exit
Perform 9100-Write-File thru 9100-Exit
.
Move "Start Element namespace prefix : " to Leader-String
Perform 5000-Move-Pointer-Next thru 5000-Exit
Perform 6000-Build-Output thru 6000-Exit
Perform 7000-Move-Ahead thru 7000-Exit
Perform 9100-Write-File thru 9100-Exit
.
2122-Exit .
Exit .

2123-XML-End-Element.
*Uncomment all the commented lines below if XEC-Feat-Full-End
*feature flag is in effect.
* Move "End Element name : " to Leader-String
Compute OP-Buffer-Start = OP-Buffer-Start + 8
* Perform 4000-Move-Pointer thru 4000-Exit
* Perform 6000-Build-Output thru 6000-Exit
* Perform 7000-Move-Ahead thru 7000-Exit
* Perform 9100-Write-File thru 9100-Exit
* .
* Move "End Element namespace : " to Leader-String
* Perform 5000-Move-Pointer-Next thru 5000-Exit
* Perform 6000-Build-Output thru 6000-Exit
* Perform 7000-Move-Ahead thru 7000-Exit
* Perform 9100-Write-File thru 9100-Exit
* .
* Move "End Element namespace prefix : " to Leader-String
* Perform 5000-Move-Pointer-Next thru 5000-Exit
* Perform 6000-Build-Output thru 6000-Exit
* Perform 7000-Move-Ahead thru 7000-Exit
* Perform 9100-Write-File thru 9100-Exit
.
2123-Exit .
Exit .

2124-XML-Attrib-Name.
Move "Attribute name : " to Leader-String
Perform 4000-Move-Pointer thru 4000-Exit
Perform 6000-Build-Output thru 6000-Exit

Appendix B. Program source files 197


Perform 7000-Move-Ahead thru 7000-Exit
Perform 9100-Write-File thru 9100-Exit
.
Move "Attribute namespace : " to Leader-String
Perform 5000-Move-Pointer-Next thru 5000-Exit
Perform 6000-Build-Output thru 6000-Exit
Perform 7000-Move-Ahead thru 7000-Exit
Perform 9100-Write-File thru 9100-Exit
.
Move "Attribute namespace prefix : " to Leader-String
Perform 5000-Move-Pointer-Next thru 5000-Exit
Perform 6000-Build-Output thru 6000-Exit
Perform 7000-Move-Ahead thru 7000-Exit
Perform 9100-Write-File thru 9100-Exit
.
2124-Exit.
Exit .

2125-XML-Attrib-Value.
Move "Attribute value : " to Leader-String
Perform 4000-Move-Pointer thru 4000-Exit
Perform 6000-Build-Output thru 6000-Exit
Perform 7000-Move-Ahead thru 7000-Exit
Perform 9100-Write-File thru 9100-Exit
.
2125-Exit.
Exit .

2126-XML-Char-Data.
*Uncomment the below commented part, if the sufficient space has
*been allocated to the output dataset in proportion to the size
*of XML document.
* Move "Char data : " to Leader-String
Perform 4000-Move-Pointer thru 4000-Exit
Perform 6000-Build-Output thru 6000-Exit
Perform 7000-Move-Ahead thru 7000-Exit
* Perform 9100-Write-File thru 9100-Exit
.
2126-Exit.
Exit .

2127-XML-NS-Decl.
Move "Namespace prefix : " to Leader-String
Perform 4000-Move-Pointer thru 4000-Exit
Perform 6000-Build-Output thru 6000-Exit
Perform 7000-Move-Ahead thru 7000-Exit
Perform 9100-Write-File thru 9100-Exit
.
Move "Namespace URI : " to Leader-String
Perform 5000-Move-Pointer-Next thru 5000-Exit
Perform 6000-Build-Output thru 6000-Exit
Perform 7000-Move-Ahead thru 7000-Exit
Perform 9100-Write-File thru 9100-Exit
.
2127-Exit.

198 XML Processing Options on z/OS


Exit .
*
2200-Handle-Warn-Reason-Code .
Move GXL1PRS-Reason-Code to GXL1PRS-Reason-Codes
Evaluate true
When GXL1PRS-InBuff-End
Move "N" to Buffer-Limit-Reached
Move zero to Input-Buffer-Length XML-Doc-Len
Move 1 to Length-Pointer
When GXL1PRS-OutBuf-End
Move spaces to Message-String
Move GXL1PRS-Input-Buff-Bytes to FW-To-Edited
String "Output buffer ended. " delimited by size
"Input bytes left to process : " delimited by size
FW-To-Edited delimited by size
into Message-String
End-String
Display Message-String
Move "N" to Buffer-Limit-Reached
Perform 2210-Adjust-Input-Buffer thru 2210-Exit
Move 1 to Length-Pointer
When GXL1PRS-InOutBuf-Ended
Move "N" to Buffer-Limit-Reached
Move zero to Input-Buffer-Length XML-Doc-Len
Move 1 to Length-Pointer
When other
Move spaces to Message-String
Move GXL1PRS-Input-Buff-Bytes to FW-To-Edited
String "Reason code not handled " delimited by size
FW-To-Edited delimited by size
into Message-String
End-String
Display Message-String
End-Evaluate
.
2200-Exit .
Exit .
*
2210-Adjust-Input-Buffer.
Move Input-Buffer(Input-Buffer-Length -
GXL1PRS-Input-Buff-Bytes + 1 :
GXL1PRS-Input-Buff-Bytes)
to Input-Buffer(1 : GXL1PRS-Input-Buff-Bytes)
Compute Input-Buffer-Length = GXL1PRS-Input-Buff-Bytes
Move "Y" to Adjusted-Buffer
.
2210-Exit .
Exit .
*
4000-Move-Pointer.
*Point past the common header record
*Length of full-word
*Get the length stored in the full-word
*Point past the full-word
*Length in the full-word to be used for ref-mod further

Appendix B. Program source files 199


*
Compute OP-Buffer-Start = OP-Buffer-Start + 8
Compute OP-Buffer-Length = 4
Move Output-Buffer (OP-Buffer-Start:OP-Buffer-Length)
to Length-String
Compute OP-Buffer-Start = OP-Buffer-Start +
OP-Buffer-Length
Compute OP-Buffer-Length = Length-Binary
.
4000-Exit .
Exit .
*
5000-Move-Pointer-Next .
*Length of full-word to get the actual length
*Get the length of the string stored in the full-word
*Point past the full-word
*Length in the full-word to be used for ref-mod further
*
Compute OP-Buffer-Length = 4
Move Output-Buffer (OP-Buffer-Start:OP-Buffer-Length)
to Length-String
Compute OP-Buffer-Start = OP-Buffer-Start +
OP-Buffer-Length
Compute OP-Buffer-Length = Length-Binary
.
5000-Exit .
Exit .
*
6000-Build-Output .
Move spaces to Write-Buffer
Output-Buffer-N
Evaluate GXL1INI-CCSID
When 1200
Move function National-Of (Leader-String)
to Write-Buffer-N
Move Output-Buffer (OP-Buffer-Start:OP-Buffer-Length)
to Write-Buffer
(2 * function Length (Leader-String) + 1 :)
Move function Display-Of (Write-Buffer-N)
to Write-Buffer
When 1208
String function National-Of (Leader-String)
delimited by size
function National-Of (Output-Buffer
(OP-Buffer-Start:OP-Buffer-Length), 1208)
delimited by size
into Output-Buffer-N
End-String
Move function Display-Of (Output-Buffer-N
(1:OP-Buffer-Length))
to Write-Buffer
When other
String Leader-String
delimited by size
Output-Buffer

200 XML Processing Options on z/OS


(OP-Buffer-Start:OP-Buffer-Length)
delimited by size
into Write-Buffer
End-String
End-Evaluate
.
6000-Exit .
Exit .

7000-Move-Ahead .
Compute OP-Buffer-Start = OP-Buffer-Start + Length-Binary.
7000-Exit .
Exit .

9000-Read-File .
Read TstXML into Read-Buffer
at end
Move "Y" to End-of-File
End-Read .
9000-Exit .
Exit .

9100-Write-File .
Write OutData-Rec from Write-Buffer .
9100-Exit .
Exit .

8000-Done .
Close TstXML OutData .
If GXL1INI-Called = "Y"
Call XMLSS-GXL1TRM using GXL1INI-PIMA
GXL1TRM-Return-Code GXL1TRM-Reason-Code
End-If
.
If GXL1PRS-Return-Code > GXL1TRM-Return-Code
Move GXL1PRS-Return-Code to Return-Code
else
Move GXL1TRM-Return-Code to Return-Code
End-If
.
8000-Exit .
Exit .

Appendix B. Program source files 201


B.7 Enterprise COBOL program to invoke z/OS XML System
Services parser with a string ID exit (without validation)
Example B-8 is an enhanced version of the sample shown in B.6 on page 186. In this
program, the String ID STRIDX (as documented in SAMPLIB) is passed to z/OS XML System
Services. As of now, this name is being passed as a job step parameter with an aim to enable
enhancement of this source to take other String ID exits.

Example B-8 Enterprise COBOL program for parsing (without validation) and buffer management.
Identification Division .
Program-ID XMLPRS2 .
*
*This is a sample program to invoke z/OS XML System Services
*to a parse an XML document without validation.
*
*This program will read from file as many times as required to
*fill the Input-Buffer to be sent to the z/OS XML parser. The
*size of this buffer has been set in this program to be 4KB.
*
*The output buffer has been set to 4KB for the sample XML document
*taken for this program. This size of the buffer ensured that, we
*do not hit x'1302' but we do encounter x'1303' or x'1304' reason
*codes.
*
*In practice though, an estimate of output buffer being twice the
*size of input buffer is good.
*
*
* Return Code Reason Code Short Description
* ----------- ----------- -----------------
* 4 1301 Input Buffer ended
* 8 1302 Output Buffer small
* 4 1303 Output Buffer ended
* 4 1304 Input and Output Buffer ended
*
*Handles encoding : UTF-16BE (1200), UTF-8 (1208) and
* EBCDIC encodings.
*
*See SYS1.MACLIB(GXL*) for data structures and constant declar-
*ations.
*
*
Environment Division .
*
Input-Output Section .
File-Control .
Select TstXML assign to TSTXML
Organization is line sequential .
*
Select OutData assign to OUTDATA
Organization is line sequential .
*
Data Division .
File Section .

202 XML Processing Options on z/OS


FD TstXML
Recording is V
Record is varying in size
depending on XML-Doc-Len .
01 TsTXML-Rec Pic X(1024) .
*
FD OutData
Recording is V
Record contains 5120 characters .
01 OutData-Rec Pic X(5120) .
*
Working-Storage Section .
01 Service-Constants .
03 Parms.
05 XEC-Min-QXDWork-Size Pic 9(09) Comp-5
Value 32768 .
05 XEC-Min-PIMA Pic 9(09) Comp-5
Value 131072 .
05 XEC-NVParse-Min-PIMA Pic 9(09) Comp-5
Value 131072 .
05 XEC-VParse-Min-PIMA Pic 9(09) Comp-5
Value 786432 .
05 XEC-Feat-Strip-Cmnts Pic 9(09) Comp-5
Value 2147483648 .
05 XEC-Feat-Full-End Pic 9(09) Comp-5
Value 16777216 .
05 XEC-ENC-UTF-8 Pic 9(09) Comp-5
Value 1208 .
03 Record-Type .
05 Parsed-Stream-RecType Pic XX .
88 Buffer-Info-Rec Value X"F00F" .
88 XML-Declaration Value X"F01F" .
88 XML-Start-Element Value X"F02F" .
88 XML-End-Element Value X"F03F" .
88 XML-Attribute-Name Value X"F04F" .
88 XML-Attribute-Value Value X"F05F" .
88 XML-Namespace-Decl Value X"F06F" .
88 XML-Character-Data Value X"F07F" .
88 XML-Start-CDATA Value X"F08F" .
88 XML-End-CDATA Value X"F09F" .
88 XML-Whitespace Value X"F0AF" .
88 XML-PI Value X"F0BF" .
88 XML-Comment Value X"F0CF" .
88 XML-DTD-Data Value X"F0DF" .
88 XML-Unresolved-Ref Value X"F0EF" .
88 XML-Aux-Info Value X"F0FF" .
88 Error-Info-Rec Value X"FEEF" .
*GXL1QXD structure .
01 GXL1QXD-Structure .
05 GXL1QXD-WorkArea Pic X(32768) .
05 GXL1QXD-WorkArea-Length Pic 9(09) Comp-5 .
05 GXL1QXD-Input-Buffer Pic X(1024) .
05 GXL1QXD-Input-Buffer-Length Pic 9(09) Comp-5 .
05 GXL1QXD-Output-Pointer Usage is Pointer .
05 GXL1QXD-Return-Code Pic 9(09) Comp-5 .

Appendix B. Program source files 203


05 GXL1QXD-Reason-Code Pic 9(09) Comp-5 .
*GXL1INI structure .
01 GXL1INI-Structure .
05 GXL1INI-PIMA Pic X(131072) .
05 GXL1INI-PIMA-Length Pic 9(09) Comp-5 .
05 GXL1INI-CCSID Pic 9(09) Comp-5 .
05 GXL1INI-Flags Pic 9(09) Comp-5 .
05 GXL1INI-Sys-Svc-Struct Usage is Pointer .
05 GXL1INI-Sys-Svc-Parm Usage is Pointer .
05 GXL1INI-Return-Code Pic 9(09) Comp-5 .
05 GXL1INI-Reason-Code Pic 9(09) Comp-5 .
*GXL1PRS structure. PIMA to be provided from elsewhere.
01 GXL1PRS-Structure .
05 GXL1PRS-Options Pic 9(09) Comp-5 .
05 GXL1PRS-Input-Buff-Address Usage pointer .
05 GXL1PRS-Input-Buff-Bytes Pic 9(09) Comp-5 .
05 GXL1PRS-Output-Buff-Address Usage pointer .
05 GXL1PRS-Output-Buff-Bytes Pic 9(09) Comp-5 .
05 GXL1PRS-Return-Code Pic 9(09) Comp-5 .
05 GXL1PRS-Reason-Code Pic 9(09) Comp-5 .
*
01 GXL-Service-Return-Codes.
05 GXL-Return-Codes Pic 9(09) Comp-5 .
05 GXL-Return-Codes-R Redefines GXL-Return-Codes.
10 GXL-Hex-Return-Code Pic X(04) .
88 XRC-Success Value X"00000000" .
88 XRC-Warning Value X"00000004" .
88 XRC-Failure Value X"00000008" .
88 XRC-Not-Well-Formed Value X"0000000C" .
88 XRC-Fatal Value X"00000010" .
88 XRC-Load-Failed Value X"00000014" .
88 XRC-Not-Valid Value X"00000018" .
05 GXL1TRM-Return-Code Pic 9(09) Comp-5 .
05 GXL1TRM-Reason-Code Pic 9(09) Comp-5 .
*
01 GXL-Service-Reason-Codes.
05 GXL1PRS-Reason-Codes Pic 9(09) Comp-5 .
05 GXL1PRS-Reason-Codes-R Redefines GXL1PRS-Reason-Codes .
10 Filler Pic X(02) .
10 GXL1PRS-Hex-Rsn-Code Pic X(02) .
88 GXL1PRS-InBuff-End Value X"1301" .
88 GXL1PRS-OutBuf-Small Value X"1302" .
88 GXL1PRS-OutBuf-End Value X"1303" .
88 GXL1PRS-InOutBuf-Ended Value X"1304" .
*
01 Output-Buffer-Common-Header .
05 OP-Buff-Rec-Type Pic XX Value Spaces .
05 OP-Buff-Rec-Flags Pic X Value Spaces .
05 Filler Pic X Value Spaces .
05 OP-Buff-Rec-Length Pic 9(09) Comp-5 Value 0 .
*
01 Buffer-Info-Record .
05 BI-DataStream-Opts Pic 9(09) Comp-5 Value 0 .
05 BI-Parse-Status Pic 9(04) Comp-5 Value 0 .
05 Filler Pic 9(04) Comp-5 Value 0 .

204 XML Processing Options on z/OS


05 BI-Buff-Length-Used Pic 9(18) Comp-5 Value 0 .
05 BI-Error-Offset Pic 9(18) Comp-5 Value 0 .
*
01 Record-Form-2-String-ID.
05 F2-Parsed-Output-Bytes Pic X(08) .
05 F2-Parsed-Output-Bytes-R redefines F2-Parsed-Output-Bytes.
10 F2-StringID-1 Pic 9(09) Comp-5 .
10 F2-StringID-2 Pic 9(09) Comp-5 .
*
01 Record-Form-3-String-ID.
05 F3-Parsed-Output-Bytes Pic X(12) .
05 F3-Parsed-Output-Bytes-R redefines F3-Parsed-Output-Bytes.
10 F3-StringID-1 Pic 9(09) Comp-5 .
10 F3-StringID-2 Pic 9(09) Comp-5 .
10 F3-StringID-3 Pic 9(09) Comp-5 .
*
01 XMLSS-Programs .
05 XMLSS-GXL1QXD Pic X(08) Value "GXL1QXD" .
05 XMLSS-GXL1INI Pic X(08) Value "GXL1INI" .
05 XMLSS-GXL1PRS Pic X(08) Value "GXL1PRS" .
05 XMLSS-GXL1TRM Pic X(08) Value "GXL1TRM" .
*
01 XML-Doc-Len Pic 9(09) .
*
01 IO-Vars .
03 Current-IO .
05 Read-Buffer Pic X(1024) Value spaces .
05 Write-Buffer Pic X(5120) Value spaces .
05 Write-Buffer-R Redefines Write-Buffer .
10 Write-Buffer-N Pic N(2560) .
05 Input-Buffer Pic X(4096) Value spaces .
05 Input-Buffer-Length Pic 9(09) Comp-5 Value 0 .
05 Output-Buffer Pic X(5120) Value spaces.
05 Output-Buffer-N Pic N(2560)
usage national Value spaces.
05 OP-Buffer-Start Pic 9(09) Comp-5 Value 0 .
05 OP-Buffer-Length Pic 9(09) Comp-5 Value 0 .
03 Prev-IO .
05 Read-Buffer-Prev Pic X(1024) Value spaces .
05 Read-Buffer-Len-Prev Pic 9(09) Comp-5 Value 0 .
*
01 Misc .
03 All-Flags.
05 GXL1INI-Called Pic X Value spaces.
05 Scan-End Pic X Value spaces.
05 Buffer-Limit-Exceeded Pic X Value "N" .
05 Buffer-Limit-Reached Pic X Value "N" .
05 End-of-File Pic X Value "N" .
05 Adjusted-Buffer Pic X Value "N" .
05 Parsing-Completed Pic X Value spaces.
05 Hard-Error Pic X Value spaces.
03 Other-Items .
05 1KB Pic 9(09) Comp-5 Value 1024.
05 Buffer-Limit Pic 9(09) Comp-5 Value 4096.
05 Call-Return-Code Pic 9(09) Comp-5 Value 0.

Appendix B. Program source files 205


05 Length-pointer Pic 9(09) Comp-5 value 1.
05 Program-Return-Code Pic 9(09) Comp-5 value 0.
05 Error-Offset-X Pic X(08) .
05 Error-Offset-R redefines Error-Offset-X .
10 Filler Pic X(04) .
10 Error-Offset-B Pic 9(09) Comp-5 .
03 WS-Work .
05 Leader-String Pic X(30) Value spaces.
05 Length-String Pic X(4) Value spaces .
05 Length-String-R Redefines Length-String .
10 Length-Binary Pic 9(09) Comp-5 .
05 Record-Form-ID Pic 9(09) Comp-5 .
05 Table-Subscript Pic 9(09) Comp-5 .
05 Test-Reason-Code Pic 9(09) Comp-5 .
05 Test-Reason-Code-R redefines Test-Reason-Code .
10 Filler Pic 9(04) Comp-5 .
10 XMLSS-Reason-Code Pic 9(04) Comp-5 .
05 Parm-CCSID Pic X(04) .
05 Parm-CCSID-R redefines Parm-CCSID .
10 Parm-CCSID-Num Pic 9(04) .
03 Output-Messages.
05 OP-Start-String-1 Pic X(25) Value
"Start Element name " .
*
01 System-Services-Exit.
05 StringID-Exit-Structure.
10 Count-Of-Exits Pic 9(09) Comp-5 .
10 Alloc-Exit Pic 9(09) Comp-5 .
10 Free-Exit Pic 9(09) Comp-5 .
10 StringID-Exit-Address Usage Function-Pointer .
05 Exit-Parm-Area-IDX.
10 XSI-DSA-Space Pic X(2048) .
10 XSI-Eye-Catcher Pic X(4) .
10 XSI-Version Pic 9(9) Comp-5 Value 0 .
10 XSI-Storage-Space Pic 9(9) Comp-5 Value 0 .
10 XSI-Diagnosis-Code Pic 9(9) Comp-5 Value 0 .
10 XSI-Next-ID Pic 9(9) Comp-5 Value 0 .
10 XSI-Index Pic 9(9) Comp-5 Value 0 .
10 XSI-String-List Occurs 100 times .
15 String-ID Pic 9(9) Comp-5 .
15 String-Length Pic 9(9) Comp-5 .
15 String-Text Pic X(80) .
05 Exit-Parm-Area-IDI.
10 Eye-Catch Pic X(8) Value "XSIEYECA".
10 Sym-Max-Size Pic 9(9) Comp-5 Value 64 .
10 Diag-Code Pic 9(9) Comp-5 Value 0 .
10 Next-Id Pic 9(9) Comp-5 Value 1 .
10 Max-Id Pic 9(9) Comp-5 Value 500.
10 Total-Size Pic 9(9) Comp-5 Value 163908 .
10 Free-Space Pic 9(9) Comp-5 Value 8192 .
10 Current-Null Pic 9(9) Comp-5 Value 0 .
10 Current-Free Usage is Pointer .
10 Tree-Null Pic 9(9) Comp-5 Value 0 .
10 Tree-Head Pic 9(9) Comp-5 Value 0 .
10 Dyn-Null Pic 9(9) Comp-5 Value 0 .

206 XML Processing Options on z/OS


10 Dyn-Area-Ptr Usage is Pointer .
10 List-Null Pic 9(9) Comp-5 Value 0 .
10 List-Ptr Usage is Pointer .
10 Call-Counter Pic 9(9) Comp-5 Value 0 .
10 ID-List Usage is Pointer
Occurs 16384 times .
10 Dyn-Area Pic 9(9) Comp-5 Value 0
Occurs 16384 times .
10 Free-Area Pic 9(9) Comp-5 Value 0
Occurs 8192 times .
*
01 Messages .
03 Message-Detail.
05 Message-String Pic X(100) Value spaces .
05 Svc-Return-Code Pic ZZZ9 .
05 Svc-Reason-Code-FW Pic 9(09) Comp-5 .
05 Svc-Reason-Code-R Redefines Svc-Reason-Code-FW .
10 Filler Pic XX .
10 Svc-Reason-Code-B Pic 9(4) Comp-5 .
05 Svc-Reason-Code Pic ZZZ9 .
05 FW-To-Edited Pic ZZZZZZ9 .
05 String-1 Pic X(30) .
03 Message-Level Pic X(07) .
88 Level-Info Value "INFO : " .
88 Level-Warn Value "WARN : " .
88 Level-Hard Value "HARD : " .
03 Various-Messages Pic X(30) .
88 Msg-Empty-File Value
"Input file is empty. " .
88 Msg-XML-Svc Value
"XML service error. " .
88 Msg-No-Exit Value
"String ID exit name provided. " .
88 Msg-Inp-Buff-End Value
"Input buffer ended. " .
88 Msg-Out-Buff-End Value
"Output buffer ended. " .
88 Msg-InOut-Buff-End Value
"Input output buffers ended. " .
*
Linkage Section .
01 Step-Parm .
05 Parm-Length Pic 9(04) Comp-5 .
05 Parm-StringID-Exit Pic X(08) .
*GXL1QXD output structure .
01 GXL1QXD-Output-Structure .
05 GXL1QXD-Version Pic 9(09) Comp-5 .
05 GXL1QXD-XML-Autodet-Value Pic 9(09) Comp-5 .
05 GXL1QXD-XML-Autodet-CCSID Pic 9(09) Comp-5 .
05 GXL1QXD-XML-Version Pic 9(04) Comp-5 .
05 GXL1QXD-XML-Release Pic 9(04) Comp-5 .
05 GXL1QXD-XML-Spec-CCSID Pic 9(09) Comp-5 .
05 GXL1QXD-XML-Flag1 Pic X(01) .
05 GXL1QXD-XML-Flag2 Pic X(01) .
05 GXL1QXD-Reserved Pic 9(04) Comp-5 .

Appendix B. Program source files 207


05 GXL1QXD-XML-Decl-Length Pic 9(09) Comp-5 .
*
Procedure Division using Step-Parm GXL1QXD-Output-Structure .
Perform 1000-Hskp thru 1000-Exit
Perform 2000-Do-Parse thru 2000-Exit
until Parsing-Completed = "Y"
or Hard-Error = "Y"
Perform 8000-Done thru 8000-Exit
.
Stop run .
*
1000-Hskp .
Open input TstXML
output OutData
.
Perform 1100-Read-Doc-Into-Buffer
thru 1100-Exit
until End-Of-File = "Y"
or Buffer-Limit-Reached = "Y"
or Buffer-Limit-Exceeded = "Y"
.
If End-of-File = "Y"
and Input-Buffer-Length = 0
Move "Y" to Hard-Error
Move 1 to Program-Return-Code
Set Level-Hard
Msg-Empty-File to true
Else
Perform 1200-Init-XMLSS thru 1200-Exit
End-If
.
1000-Exit .
Exit .
*
1100-Read-Doc-Into-Buffer .
Perform 9000-Read-File thru 9000-Exit
If End-Of-File = "Y"
Go to 1100-Exit
End-If
*
Add XML-Doc-Len to Input-Buffer-Length
If Input-Buffer-Length < Buffer-Limit
String Read-Buffer (1:XML-Doc-Len) delimited by size
into Input-Buffer
with pointer Length-pointer
End-String
End-If
*
If Input-Buffer-Length = Buffer-Limit
String Read-Buffer (1:XML-Doc-Len) delimited by size
into Input-Buffer
with pointer Length-pointer
End-String
Move "Y" to Buffer-Limit-Reached
End-If

208 XML Processing Options on z/OS


*
If Input-Buffer-Length > Buffer-Limit
Subtract XML-Doc-Len from Input-Buffer-Length
Move XML-Doc-Len to Read-Buffer-Len-Prev
Move Read-Buffer (1:Read-Buffer-Len-Prev)
to Read-Buffer-Prev (1:Read-Buffer-Len-Prev)
Move "Y" to Buffer-Limit-Exceeded
End-If
.
1100-Exit .
Exit .
*
1200-Init-XMLSS .
Perform 1210-Get-CCSID thru 1210-Exit
If Hard-Error = "Y"
Continue
Else
Perform 1220-Do-Initialise thru 1220-Exit
End-If
.
1200-Exit .
Exit .
*
1210-Get-CCSID .
Move spaces to GXL1QXD-WorkArea
Move XEC-Min-QXDWork-Size
to GXL1QXD-WorkArea-Length
Move Input-Buffer(1:Input-Buffer-Length)
to GXL1QXD-Input-Buffer
Move Input-Buffer-Length
to GXL1QXD-Input-Buffer-Length
Move 0 to GXL1QXD-Return-Code
GXL1QXD-Reason-Code
.
Call XMLSS-GXL1QXD using
GXL1QXD-WorkArea
GXL1QXD-WorkArea-Length
GXL1QXD-Input-Buffer
GXL1QXD-Input-Buffer-Length
GXL1QXD-Output-Pointer
GXL1QXD-Return-Code
GXL1QXD-Reason-Code
returning Call-Return-Code
.
Move spaces to Message-String
If GXL1QXD-Return-Code > 0
Move GXL1QXD-Return-Code to Svc-Return-Code
Move GXL1QXD-Reason-Code to Svc-Reason-Code-FW
Move Svc-Reason-Code-B to Svc-Reason-Code
String "GXL1QXD Return Code : " delimited by size
Svc-Return-Code delimited by size
" Reason Code : " delimited by size
Svc-Reason-Code delimited by size
into Message-String
Display Message-String

Appendix B. Program source files 209


Move GXL1QXD-Return-Code to Program-Return-Code
Move "Y" to Hard-Error
Set Level-Hard
Msg-XML-Svc to true
Else
Set address of GXL1QXD-Output-Structure
to GXL1QXD-Output-Pointer
Move GXL1QXD-XML-Autodet-CCSID to FW-To-Edited
Set Level-Info to true
String Message-Level delimited by size
"Autodetected CCSID : " delimited by size
FW-To-Edited delimited by size
into Message-String
Display Message-String
Move GXL1QXD-XML-Spec-CCSID to FW-To-Edited
String Message-Level delimited by size
"Specified CCSID : " delimited by size
FW-To-Edited delimited by size
into Message-String
Display Message-String
End-If
.
1210-Exit .
Exit .
*
1220-Do-Initialise .
If Parm-Length = 0
Set Level-Hard
Msg-No-Exit to true
Move "Y" to Hard-Error
String Message-Level delimited by size
Various-Messages delimited by size
into Message-String
End-String
Display Message-String
Move 1 to Program-Return-Code
Go to 1220-Exit
End-If
.
Move spaces to GXL1INI-PIMA
Move GXL1QXD-XML-Autodet-CCSID to GXL1INI-CCSID
Compute GXL1INI-PIMA-Length = XEC-NVParse-Min-PIMA
.
Move 3 to Count-Of-Exits
Move zero to Alloc-Exit Free-Exit
Set StringID-Exit-Address to entry Parm-StringID-Exit
Set GXL1INI-Sys-Svc-Parm to
* address of Exit-Parm-Area
address of Exit-Parm-Area-IDX
Move 10872 to XSI-Storage-Space
* Set List-Ptr to address of ID-List(1)
* Set Dyn-Area-Ptr to address of Dyn-Area(1)
* Set Current-Free to address of Free-Area(1)
Move spaces to Message-String
Set Level-Info to true

210 XML Processing Options on z/OS


String Message-Level delimited by size
"String ID exit " delimited by size
Parm-StringID-Exit delimited by size
" will be used." delimited by size
into Message-String
End-String
Display Message-String
.
Compute GXL1INI-Flags = XEC-Feat-Strip-Cmnts
+ XEC-Feat-Full-End
Move zero to GXL1INI-Return-Code
GXL1INI-Reason-Code
.
Call XMLSS-GXL1INI
using GXL1INI-PIMA
GXL1INI-PIMA-Length
GXL1INI-CCSID
GXL1INI-Flags
StringID-Exit-Structure
GXL1INI-Sys-Svc-Parm
GXL1INI-Return-Code
GXL1INI-Reason-Code
.
If GXL1INI-Return-Code > 0
Move GXL1INI-Return-Code to Svc-Return-Code
Move GXL1INI-Reason-Code to Svc-Reason-Code-FW
Move Svc-Reason-Code-B to Svc-Reason-Code
String "GXL1INI Return Code : " delimited by size
Svc-Return-Code delimited by size
" Reason Code : " delimited by size
Svc-Reason-Code delimited by size
into Message-String
Display Message-String
Move "Y" to Hard-Error
Move GXL1INI-Return-Code to Program-Return-Code
Set Level-Hard
Msg-XML-Svc to true
Else
Move "Y" to GXL1INI-Called
End-If
.
1220-Exit .
Exit .
*
2000-Do-Parse .
Initialize GXL1PRS-Structure
Set GXL1PRS-Input-Buff-Address to
address of Input-Buffer
Set GXL1PRS-Output-Buff-Address to
address of Output-Buffer
Move Input-Buffer-Length to GXL1PRS-Input-Buff-Bytes
Compute GXL1PRS-Output-Buff-Bytes = 5 * 1KB
.
Call XMLSS-GXL1PRS using
GXL1INI-PIMA

Appendix B. Program source files 211


GXL1PRS-Options
GXL1PRS-Input-Buff-Address
GXL1PRS-Input-Buff-Bytes
GXL1PRS-Output-Buff-Address
GXL1PRS-Output-Buff-Bytes
GXL1PRS-Return-Code
GXL1PRS-Reason-Code
returning Call-Return-Code
.
Move spaces to Message-String
Move GXL1PRS-Return-Code to Svc-Return-Code
Move GXL1PRS-Reason-Code to Svc-Reason-Code-FW
Move Svc-Reason-Code-B to Svc-Reason-Code
Move Input-Buffer-Length to FW-To-Edited
.
If GXL1PRS-Return-Code <= 4
Set Level-Info to true
Else
Set Level-Hard to true
End-If
.
String Message-Level delimited by size
"Length Input Buffer : " delimited by size
FW-To-Edited delimited by size
" GXL1PRS Return Code : " delimited by size
Svc-Return-Code delimited by size
" Reason Code : " delimited by size
Svc-Reason-Code delimited by size
into Message-String
Display Message-String
.
Move GXL1PRS-Return-Code to GXL-Return-Codes
Evaluate true
When XRC-Success
Perform 2100-Process-Output thru 2100-Exit
Move "Y" to Parsing-Completed
When XRC-Warning
Perform 2100-Process-Output thru 2100-Exit
Perform 2200-Handle-Warn-Reason-Code thru 2200-Exit
When XRC-Failure
Move spaces to Message-String
Move "Failure." to String-1
Move "Y" to Hard-Error
Perform 2100-Process-Output thru 2100-Exit
When XRC-Not-Well-Formed
Move spaces to Message-String
Move "Document not well formed." to String-1
Move "Y" to Hard-Error
Perform 2100-Process-Output thru 2100-Exit
When XRC-Fatal
Move spaces to Message-String
Move "Fatal Error." to String-1
Move "Y" to Hard-Error
Perform 2100-Process-Output thru 2100-Exit
When XRC-Load-Failed

212 XML Processing Options on z/OS


Move spaces to Message-String
Move "Service not loaded." to String-1
Move "Y" to Hard-Error
Perform 2100-Process-Output thru 2100-Exit
When XRC-Not-Valid
Move spaces to Message-String
Move "Doc not valid as per schema." to String-1
Move "Y" to Hard-Error
Perform 2100-Process-Output thru 2100-Exit
End-Evaluate
.
If Hard-Error = "Y"
or Parsing-Completed = "Y"
Go to 2000-Exit
End-If
.
Evaluate End-Of-File
also Adjusted-Buffer
When "Y" also "Y"
Continue
When "Y" also "N"
Move "Y" to Parsing-Completed
When "N" also "Y"
Continue
When "N" also "N"
If Buffer-Limit-Exceeded = "Y"
Move Read-Buffer-Prev (1:Read-Buffer-Len-Prev)
to Input-Buffer (1:Read-Buffer-Len-Prev)
Move Read-Buffer-Len-Prev
to Input-Buffer-Length
Move "N" to Buffer-Limit-Exceeded
Move spaces to Read-Buffer-Prev
Move zero to Read-Buffer-Len-Prev
Else
Perform 1100-Read-Doc-Into-Buffer thru 1100-Exit
until End-Of-File = "Y"
or Buffer-Limit-Reached = "Y"
or Buffer-Limit-Exceeded = "Y"
End-If
End-Evaluate
*
Move "N" to Adjusted-Buffer
.
2000-Exit .
Exit .
*
2100-Process-Output .
Move 1 to OP-Buffer-Start
Move 8 to OP-Buffer-Length
Move Output-Buffer (OP-Buffer-Start:OP-Buffer-Length)
to Output-Buffer-Common-Header
Compute OP-Buffer-Start = OP-Buffer-Length + 1
Compute OP-Buffer-Length = OP-Buff-Rec-Length - 8
Move Output-Buffer (OP-Buffer-Start:OP-Buffer-Length)
to Buffer-Info-Record

Appendix B. Program source files 213


.
If BI-Error-Offset > 0
Move spaces to Message-String
Perform 2110-Get-Error-Record thru 2110-Exit
Go to 2100-Exit
End-If
.
Compute OP-Buffer-Start = OP-Buffer-Start +
OP-Buffer-Length
Compute OP-Buffer-Length = 0
.
Move space to Scan-End
Perform 2120-Scan-Output-Buffer thru 2120-Exit
until Scan-End = "Y"
.
2100-Exit .
Exit .
*
2110-Get-Error-Record .
*Point after 8 bytes of Return and reason codes to 8 bytes of
*error offset .
Move Output-Buffer(BI-Error-Offset + 17 : 8)
to Error-Offset-X
Move Error-Offset-B to FW-To-Edited
Set Level-Hard to true
String Message-Level delimited by size
"Error offset in doc : " delimited by size
FW-To-Edited delimited by size
into Message-String
Display Message-String
.
2110-Exit .
Exit .
*
2120-Scan-Output-Buffer .
Move Output-Buffer (OP-Buffer-Start:2)
to Parsed-Stream-RecType
.
Evaluate true
When XML-Declaration
Perform 2121-XML-Declaration thru 2121-Exit
When XML-Start-Element
Perform 2122-XML-Start-Element thru 2122-Exit
When XML-End-Element
Perform 2123-XML-End-Element thru 2123-Exit
When XML-Attribute-Name
Perform 2124-XML-Attrib-Name thru 2124-Exit
When XML-Attribute-Value
Perform 2125-XML-Attrib-Value thru 2125-Exit
When XML-Character-Data
Perform 2126-XML-Char-Data thru 2126-Exit
When XML-Namespace-Decl
Perform 2127-XML-NS-Decl thru 2127-Exit
When other
Move spaces to Message-String

214 XML Processing Options on z/OS


Set Level-Hard to true
String Message-Level delimited by size
"Rec Type : " delimited by size
Parsed-Stream-RecType delimited by size
" Not handled in this code. Aborting."
delimited by size
into Message-String
End-String
Display Message-String
Move "Y" to Scan-End Hard-Error
Move 1 to Program-Return-Code
End-Evaluate
.
If OP-Buffer-Start >= BI-Buff-Length-Used
Move "Y" to Scan-End
End-If
.
2120-Exit .
Exit .
*
2121-XML-Declaration .
Move "XML Version : " to Leader-String
Perform 4000-Move-Pointer thru 4000-Exit
Perform 6000-Build-Output thru 6000-Exit
Perform 7000-Move-Ahead thru 7000-Exit
Perform 9100-Write-File thru 9100-Exit
.
Move "XML Encoding : " to Leader-String
Perform 5000-Move-Pointer-Next thru 5000-Exit
Perform 6000-Build-Output thru 6000-Exit
Perform 7000-Move-Ahead thru 7000-Exit
Perform 9100-Write-File thru 9100-Exit
.
Move "XML Standalone : " to Leader-String
Perform 5000-Move-Pointer-Next thru 5000-Exit
Perform 6000-Build-Output thru 6000-Exit
Perform 7000-Move-Ahead thru 7000-Exit
Perform 9100-Write-File thru 9100-Exit
.
2121-Exit .
Exit .
*
2122-XML-Start-Element .
Move "Start Element name : " to Leader-String
Move 3 to Record-Form-ID
Perform 3000-Move-Pointer-StringID thru 3000-Exit
Perform A000-Get-Record-Form-3 thru A000-Exit
*
Move F3-StringID-1 to Table-Subscript
Perform E000-Get-String-of-StringID thru E000-Exit
Perform 9100-Write-File thru 9100-Exit
*
Move F3-StringID-2 to Table-Subscript
Perform E000-Get-String-of-StringID thru E000-Exit
Perform 9100-Write-File thru 9100-Exit

Appendix B. Program source files 215


*
Move F3-StringID-3 to Table-Subscript
Perform E000-Get-String-of-StringID thru E000-Exit
Perform 9100-Write-File thru 9100-Exit
*
Perform F000-Move-Ahead thru F000-Exit
.
2122-Exit .
Exit .
*
2123-XML-End-Element.
Move "End Element name : " to Leader-String
Move 3 to Record-Form-ID
Perform 3000-Move-Pointer-StringID thru 3000-Exit
Perform A000-Get-Record-Form-3 thru A000-Exit
*
Move F3-StringID-1 to Table-Subscript
Perform E000-Get-String-of-StringID thru E000-Exit
Perform 9100-Write-File thru 9100-Exit
*
Move F3-StringID-2 to Table-Subscript
Perform E000-Get-String-of-StringID thru E000-Exit
Perform 9100-Write-File thru 9100-Exit
*
Move F3-StringID-3 to Table-Subscript
Perform E000-Get-String-of-StringID thru E000-Exit
Perform 9100-Write-File thru 9100-Exit
*
Perform F000-Move-Ahead thru F000-Exit
.
2123-Exit .
Exit .
*
2124-XML-Attrib-Name.
Move 3 to Record-Form-ID
Perform 3000-Move-Pointer-StringID thru 3000-Exit
Perform A000-Get-Record-Form-3 thru A000-Exit
*
Move F3-StringID-1 to Table-Subscript
Perform E000-Get-String-of-StringID thru E000-Exit
Perform 9100-Write-File thru 9100-Exit
*
Move F3-StringID-2 to Table-Subscript
Perform E000-Get-String-of-StringID thru E000-Exit
Perform 9100-Write-File thru 9100-Exit
*
Move F3-StringID-3 to Table-Subscript
Perform E000-Get-String-of-StringID thru E000-Exit
Perform 9100-Write-File thru 9100-Exit
*
Perform F000-Move-Ahead thru F000-Exit
.
2124-Exit.
Exit .

216 XML Processing Options on z/OS


2125-XML-Attrib-Value.
Move "Attribute value : " to Leader-String
Perform 4000-Move-Pointer thru 4000-Exit
Perform 6000-Build-Output thru 6000-Exit
Perform 7000-Move-Ahead thru 7000-Exit
Perform 9100-Write-File thru 9100-Exit
.
2125-Exit.
Exit .
*
2126-XML-Char-Data.
Move "Char data : " to Leader-String
Perform 4000-Move-Pointer thru 4000-Exit
Perform 6000-Build-Output thru 6000-Exit
Perform 7000-Move-Ahead thru 7000-Exit
* Perform 9100-Write-File thru 9100-Exit
.
2126-Exit.
Exit .
*
2127-XML-NS-Decl.
Move "XML NS : " to Leader-String
Move 2 to Record-Form-ID
Perform 3000-Move-Pointer-StringID thru 3000-Exit
Perform B000-Get-Record-Form-2 thru B000-Exit
*
Move F2-StringID-1 to Table-Subscript
Perform E000-Get-String-of-StringID thru E000-Exit
Perform 9100-Write-File thru 9100-Exit
*
Move F2-StringID-2 to Table-Subscript
Perform E000-Get-String-of-StringID thru E000-Exit
Perform 9100-Write-File thru 9100-Exit
*
Perform F000-Move-Ahead thru F000-Exit
.
2127-Exit.
Exit .
*
2200-Handle-Warn-Reason-Code .
Move spaces to Message-String
Set Level-Warn to true
Move GXL1PRS-Reason-Code to GXL1PRS-Reason-Codes
Evaluate true
When GXL1PRS-InBuff-End
Move "N" to Buffer-Limit-Reached
Move zero to Input-Buffer-Length XML-Doc-Len
Move 1 to Length-Pointer
Set Msg-Inp-Buff-End to true
String Message-Level delimited by size
Various-Messages delimited by size
into Message-String
End-String
Display Message-String
When GXL1PRS-OutBuf-End

Appendix B. Program source files 217


Move GXL1PRS-Input-Buff-Bytes to FW-To-Edited
Set Msg-Out-Buff-End to true
String Message-Level delimited by size
Various-Messages delimited by size
"Input bytes left to process : " delimited by size
FW-To-Edited delimited by size
into Message-String
End-String
Display Message-String
Move "N" to Buffer-Limit-Reached
Perform 2210-Adjust-Input-Buffer thru 2210-Exit
Move 1 to Length-Pointer
When GXL1PRS-InOutBuf-Ended
Set Msg-InOut-Buff-End to true
String Message-Level delimited by size
Various-Messages delimited by size
into Message-String
End-String
Move "N" to Buffer-Limit-Reached
Move zero to Input-Buffer-Length XML-Doc-Len
Move 1 to Length-Pointer
When other
String Message-Level delimited by size
"Reason code not handled " delimited by size
into Message-String
End-String
Display Message-String
End-Evaluate
.
2200-Exit .
Exit .
*
2210-Adjust-Input-Buffer.
Move Input-Buffer(Input-Buffer-Length -
GXL1PRS-Input-Buff-Bytes + 1 :
GXL1PRS-Input-Buff-Bytes)
to Input-Buffer(1 : GXL1PRS-Input-Buff-Bytes)
Compute Input-Buffer-Length = GXL1PRS-Input-Buff-Bytes
Move "Y" to Adjusted-Buffer
.
2210-Exit .
Exit .
*
3000-Move-Pointer-StringID.
*Point past the common header record
Compute OP-Buffer-Start = OP-Buffer-Start + 8
.
3000-Exit .
Exit .
*
A000-Get-Record-Form-3.
*3 FW equals 12 bytes
Compute OP-Buffer-Length = 12
Move Output-Buffer (OP-Buffer-Start : OP-Buffer-Length)
to F3-Parsed-Output-Bytes.

218 XML Processing Options on z/OS


A000-Exit .
Exit .
*
B000-Get-Record-Form-2.
*2 FW equals 8 bytes
Compute OP-Buffer-Length = 8
Move Output-Buffer (OP-Buffer-Start : OP-Buffer-Length)
to F2-Parsed-Output-Bytes.
B000-Exit .
Exit .
*
C000-Build-Output-Form2.
If F2-StringID-1 > 0
Move F2-StringID-1 to Table-Subscript
Perform E000-Get-String-of-StringID thru E000-Exit
Perform 9100-Write-File thru 9100-Exit
End-If
.
If F2-StringID-2 > 0
Move F2-StringID-2 to Table-Subscript
Perform E000-Get-String-of-StringID thru E000-Exit
Perform 9100-Write-File thru 9100-Exit
End-If
.
C000-Exit.
Exit.
*
D000-Build-Output-Form3.
If F3-StringID-1 > 0
Move F3-StringID-1 to Table-Subscript
Perform E000-Get-String-of-StringID thru E000-Exit
Perform 9100-Write-File thru 9100-Exit
End-If
.
If F3-StringID-2 > 0
Move F3-StringID-2 to Table-Subscript
Perform E000-Get-String-of-StringID thru E000-Exit
Perform 9100-Write-File thru 9100-Exit
End-If
.
If F3-StringID-3 > 0
Move F3-StringID-3 to Table-Subscript
Perform E000-Get-String-of-StringID thru E000-Exit
Perform 9100-Write-File thru 9100-Exit
End-If
.
D000-Exit.
Exit.
*
E000-Get-String-of-StringID.
Move spaces to Write-Buffer
Output-Buffer-N
*
Evaluate GXL1INI-CCSID
When 1200

Appendix B. Program source files 219


Move function National-Of (Leader-String)
to Write-Buffer-N
Move String-Text(Table-Subscript)
(1:String-Length(Table-Subscript))
to Write-Buffer
(2 * function Length (Leader-String) + 1 : )
Move function Display-Of (Write-Buffer-N)
to Write-Buffer
When 1208
String function National-Of (Leader-String)
delimited by size
function National-Of
(String-Text(Table-Subscript)
(1:String-Length(Table-Subscript))
, 1208)
delimited by size
into Output-Buffer-N
End-String
Move function Display-Of (Output-Buffer-N)
to Write-Buffer
When other
String Leader-String
delimited by size
String-Text(Table-Subscript)
(1:String-Length(Table-Subscript))
delimited by size
into Write-Buffer
End-String
End-Evaluate
.
E000-Exit .
Exit .
*
F000-Move-Ahead .
Compute OP-Buffer-Start = OP-Buffer-Start +
4 * Record-Form-ID .
F000-Exit .
Exit .
*
4000-Move-Pointer.
*Point past the common header record
*Length of full-word
*Get the length stored in the full-word
*Point past the full-word
*Length in the full-word to be used for ref-mod further
*
Compute OP-Buffer-Start = OP-Buffer-Start + 8
Compute OP-Buffer-Length = 4
Move Output-Buffer (OP-Buffer-Start:OP-Buffer-Length)
to Length-String
Compute OP-Buffer-Start = OP-Buffer-Start +
OP-Buffer-Length
Compute OP-Buffer-Length = Length-Binary
.
4000-Exit .

220 XML Processing Options on z/OS


Exit .
*
5000-Move-Pointer-Next .
*Length of full-word to get the actual length
*Get the length of the string stored in the full-word
*Point past the full-word
*Length in the full-word to be used for ref-mod further
*
Compute OP-Buffer-Length = 4
Move Output-Buffer (OP-Buffer-Start:OP-Buffer-Length)
to Length-String
Compute OP-Buffer-Start = OP-Buffer-Start +
OP-Buffer-Length
Compute OP-Buffer-Length = Length-Binary
.
5000-Exit .
Exit .
*
6000-Build-Output .
Move spaces to Write-Buffer
Output-Buffer-N
*
Evaluate GXL1INI-CCSID
When 1200
Move function National-Of (Leader-String)
to Write-Buffer-N
Move Output-Buffer (OP-Buffer-Start:OP-Buffer-Length)
to Write-Buffer
(2 * function Length (Leader-String) + 1 : )
Move function Display-Of (Write-Buffer-N)
to Write-Buffer
When 1208
String function National-Of (Leader-String)
delimited by size
function National-Of (Output-Buffer
(OP-Buffer-Start:OP-Buffer-Length), 1208)
delimited by size
into Output-Buffer-N
End-String
Move function Display-Of (Output-Buffer-N)
to Write-Buffer
When other
String Leader-String
delimited by size
Output-Buffer
(OP-Buffer-Start:OP-Buffer-Length)
delimited by size
into Write-Buffer
End-String
End-Evaluate
.
6000-Exit .
Exit .
*
7000-Move-Ahead .

Appendix B. Program source files 221


Compute OP-Buffer-Start = OP-Buffer-Start + Length-Binary.
7000-Exit .
Exit .
*
9000-Read-File .
Read TstXML into Read-Buffer
at end
Move "Y" to End-of-File
End-Read .
9000-Exit .
Exit .
*
9100-Write-File .
Write OutData-Rec from Write-Buffer .
9100-Exit .
Exit .
*
8000-Done .
Close TstXML OutData .
If GXL1INI-Called = "Y"
Call XMLSS-GXL1TRM using GXL1INI-PIMA
GXL1TRM-Return-Code GXL1TRM-Reason-Code
End-If
.
Move Program-Return-Code to Return-Code
.
8000-Exit .
Exit .

222 XML Processing Options on z/OS


B.8 C program to traverse a z/OS XML parsed record stream
and display the information in it
Example B-9 is a C program that illustrates how to navigate through the records of a z/OS
XML data stream. The navigation is facilitated through the use of several macros that are
defined at the top of the program source. This program expects that the user has parsed an
EBCDIC XML document using z/OS XML and has saved the output stream in a file. Note the
limitations on the size of the input file, as defined by the REC_STREAM_BUF_LEN constant.

Example B-9 shows code that can traverse the records generated by the z/OS XML parser:

Example B-9 C code to traverse an XML parsed record stream


// *************************************************************
//
// Description: Traverse and display the records of a z/OS XMl
// record stream.
//
// This code is based on the following assumptions
// about the datastream:
// - It is generated from an EBCDIC document
// - The full end feature (GXLHXEC_FEAT_FULL_END)
// is used
// - The tokenize whitespace feature
// (GXLHXEC_FEAT_TOKENIZE_WHITESPACE) is used
//
// *************************************************************
#define POSIX_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <gxlhxml.h>

// Local prototypes
int ReadFile(char *, char *, size_t);
void PrintBufInfo(void *);
void PrintXMLDecl(void *);
void PrintEAName(void *);
void PrintNSName(void *);
void PrintPI(void *);
void PrintDTD(void *);
void PrintAuxInfo(void *);
void PrintError(void *);
void PrintLenVal(GXLHXEH_VALUE *, int);

// Local constants
#define REC_STREAM_BUF_LEN 1048576

#define NULLCHAR 0x00


#define NEWLINE '\n'

#define LINE_WIDTH 80

#define SUCCESS 0

Appendix B. Program source files 223


#define FAILURE 1

#define OFF 0
#define ON 1

// -------------------------------------------------------------
// Macros for traversing the z/OS XML parse record stream
// -------------------------------------------------------------
// Navigate to the next record in the binary stream.
#define NEXTREC(p) (GXLHXEH_RECORD *)((int)p + p->XEH_RecLen)

// Navigate to the next value in a given record.


#define NEXTVAL(p) (GXLHXEH_VALUE *)((int)p + p->XEH_ValLen + \
sizeof(p->XEH_ValLen))

// Provide access to assorted fields of the record header.


#define RECTOK(p) (p->XEH_TokType)
#define RECFLGS(p) (p->XEH_Flags)
#define RECRSV(p) (p->XEH_Reserved)
#define RECLEN(p) (p->XEH_RecLen)

// Provide access to the values of a given record.


#define RECVALS(p) (void *)&(p->XEH_Values)
#define RECLVPAIR(p) (GXLHXEH_VALUE *)(void *)&(p->XEH_Values)

// Provide access to assorted fields of a given value.


#define VALLEN(p) (p->XEH_ValLen)
#define VALTEXT(p) (p->XEH_ValText)

// Check that the content of a given element matches a


// specified string.
#define VALMATCH(p,str) (!strncmp(&(VALTEXT(p)),str,VALLEN(p)))

// Test the record header flags.


#define RECCONT(p) (p->XEH_Flags & XEH_CONTINUED)
#define RECNOESC(p) (p->XEH_Flags & XEH_NO_ESCAPES)
#define RECDEFAULT(p) (p->XEH_Flags & XEH_DEFAULT)

// Test the datastream options flags.


#define DSOPS(p) (p->XEH_DSOpts)
#define DSOPSTRID(p) (p->XEH_DSOpts & XEH_STRINGID)
#define DSOPSTRCMT(p) (p->XEH_DSOpts & XEH_STRIPCMTS)
#define DSOPTKWHSP(p) (p->XEH_DSOpts & XEH_TOKWHSP)
#define DSOPCDCHAR(p) (p->XEH_DSOpts & XEH_CDASCHAR)
#define DSOPFULEND(p) (p->XEH_DSOpts & XEH_FULLEND)
#define DSOPVALID(p) (p->XEH_DSOpts & XEH_VALIDATED)
#define DSOPSRCOFF(p) (p->XEH_DSOpts & XEH_SOURCEOFFSET)

// Test the parser status flag.


#define PRSSTAT(p) (p->XEH_PrsStat)
#define PRSUNREF(p) (p->XEH_PrsStat & XEH_UNRESOLVEDREF)

// Provide access to assorted fields of the aux info record.


#define AUXTYPE(p) (p->XEH_AUXType)

224 XML Processing Options on z/OS


#define AUXDATA(p) (p->XEH_AUXData)

// Test the aux info flags.


#define AUXFLGS(p) (p->XEH_AUXFlag)
#define AUXFLVAL(p) (p->XEH_AUXFlag & XEH_AUX_LONG_VALUE)
#define AUXFENTY(p) (p->XEH_AUXFlag & XEH_AUX_ENTITY)

// Provide access to assorted fields of the error record.


#define ERRRC(p) (p->XEH_RetCode)
#define ERRRSN(p) (p->XEH_RsnCode)
#define ERROFFSET(p) (p->XEH_DocOffset)

// -------------------------------------------------------------
// Mainline code
// -------------------------------------------------------------
int main(int argc,
char **argv)
{ // start of main
char *pZOSXmlFileName;
char ZOSXml[REC_STREAM_BUF_LEN];
int lZOSXml;

GXLHXEH_RECORD *pRec = (GXLHXEH_RECORD *)ZOSXml;

int i = 0;
int j = 0;
int rc = 0;

// Get the name of the file with the z/OS XML datastream.
if (argc >= 0)
pZOSXmlFileName = argv[1];

else
{ // no file name secified
printf("Error - no file name specified.\n");
rc = FAILURE;
goto done;
} // no file name secified

// Read the record stream in so we can traverse it.


lZOSXml = ReadFile(pZOSXmlFileName,ZOSXml,REC_STREAM_BUF_LEN);

if (!lZOSXml)
{ // read the z/OS XML failed
rc = FAILURE;
goto done;
} // read the z/OS XML failed

// -------------------------------------------------------------
// This main loop traverses the record stream, and prints out
// what it sees.
// -------------------------------------------------------------
printf("\n----------------------------------------------------------\n");

Appendix B. Program source files 225


while(i < lZOSXml)
{ // loop through the record stream
void *pVals; // void pointer to make the compiler happy

// First, output the token type. Note that these token types
// are order in the switch statement below based roughly on the
// frequency with which they are likely to appear in a given
// document.
printf("+%04X ",i);

switch(RECTOK(pRec))
{ // token type switch
case GXLHXEC_TOK_START_ELEM:
printf("START_ELEM - "); break;
case GXLHXEC_TOK_END_ELEM:
printf("END_ELEM - "); break;
case GXLHXEC_TOK_ATTR_NAME:
printf("ATTR_NAME - "); break;
case GXLHXEC_TOK_ATTR_VALUE:
printf("ATTR_VALUE - "); break;
case GXLHXEC_TOK_NS_DECL:
printf("NS_DECL - "); break;
case GXLHXEC_TOK_CHAR_DATA:
printf("CHAR_DATA - "); break;
case GXLHXEC_TOK_COMMENT:
printf("COMMENT - "); break;
case GXLHXEC_TOK_BUFFER_INFO:
printf("BUFFER_INFO - "); break;
case GXLHXEC_TOK_XML_DECL:
printf("XML_DECL - "); break;
case GXLHXEC_TOK_START_CDATA:
printf("START_CDATA - "); break;
case GXLHXEC_TOK_END_CDATA:
printf("END_CDATA - "); break;
case GXLHXEC_TOK_WHITESPACE:
printf("WHITESPACE - "); break;
case GXLHXEC_TOK_PI:
printf("PI - "); break;
case GXLHXEC_TOK_DTD_DATA:
printf("DTD_DATA - "); break;
case GXLHXEC_TOK_UNRESOLVED_REF:
printf("UNRES_REF - "); break;
case GXLHXEC_TOK_AUX_INFO:
printf("AUX_INFO - "); break;
case GXLHXEC_TOK_ERROR:
printf("ERROR - "); break;
default:
printf("UNRECOGNIZED - ");
break; // default
} // token type switch

// Display the rest of the header record.


printf("len: %08X flags: %02X rsv: %02X\n",RECLEN(pRec),
RECFLGS(pRec), RECRSV(pRec));

226 XML Processing Options on z/OS


// Display the header flags.
if (RECFLGS(pRec))
{ // display header flags
printf(" header flags: ");
if (RECCONT(pRec))
printf("CONTINUED ");
if (RECNOESC(pRec))
printf("NO_ESCAPES ");
if (RECDEFAULT(pRec))
printf("XEH_DEFAULT");
printf("\n");
} // display header flags

// Now print out the type-specific information for each record.


pVals = RECVALS(pRec);

switch(RECTOK(pRec))
{ // token type switch
case GXLHXEC_TOK_START_ELEM:
case GXLHXEC_TOK_END_ELEM:
case GXLHXEC_TOK_ATTR_NAME:
PrintEAName(pVals);
break;

// Type zero records have no data to print.


case GXLHXEC_TOK_START_CDATA:
case GXLHXEC_TOK_END_CDATA:
break; // nothing to do here

case GXLHXEC_TOK_NS_DECL:
PrintNSName(pVals);
break;

// Type one records - single value to print.


// Skip over whitespace-only character data.
case GXLHXEC_TOK_WHITESPACE:
break;

case GXLHXEC_TOK_ATTR_VALUE:
case GXLHXEC_TOK_CHAR_DATA:
case GXLHXEC_TOK_COMMENT:
case GXLHXEC_TOK_UNRESOLVED_REF:
PrintLenVal((GXLHXEH_VALUE *)pVals,4);
printf("\n");
break;

case GXLHXEC_TOK_BUFFER_INFO:
PrintBufInfo(pVals);
break;

case GXLHXEC_TOK_XML_DECL:
PrintXMLDecl(pVals);
break;

case GXLHXEC_TOK_PI:

Appendix B. Program source files 227


PrintPI(pVals);
break;

case GXLHXEC_TOK_DTD_DATA:
PrintDTD(pVals);
break;

case GXLHXEC_TOK_AUX_INFO:
PrintAuxInfo(pVals);
break;

case GXLHXEC_TOK_ERROR:
PrintError(pVals);
break;

default:
break; // default
} // token type switch

// Bump to the next record in the buffer.


i += RECLEN(pRec);
pRec = NEXTREC(pRec);
j++;
} // loop through the record stream

printf("\n----------------------------------------------------------\n");

// Finish up and return to the caller.


done:
return(rc);
} // end of main

// -------------------------------------------------------------
// Local subroutines
// -------------------------------------------------------------
// *************************************************************
// ReadFile - read a file and return and return all of its
// contents.
// *************************************************************
ssize_t ReadFile(char *pFileName,
char *pFileBuf,
size_t lFileBuf)
{ // start of ReadFile
ssize_t nBytesRead = 0; // number of bytes read
int fd; // descriptor for file to read

// First, open the file for read.


fd = open(pFileName,O_RDONLY);

if (fd >= 0)
{ // file is open
nBytesRead = read(fd,pFileBuf,lFileBuf);

if (nBytesRead <= 0)

228 XML Processing Options on z/OS


{ // read failed
printf("Error - file read failed.\n");
nBytesRead = 0;
} // read failed

close(fd);
} // file is open

else
{ // file open failed
printf("Error - open %s failed\n", pFileName);
nBytesRead = 0;
} // file open failed

return(nBytesRead);
} // end of ReadFile

// *************************************************************
// PrintBufInfo - print record-specific info for buffer info records.
// *************************************************************
void PrintBufInfo(void *pVal)
{ // start of PrintBufInfo
GXLHXEH_BUFINFODATA *pBIVal;

pBIVal = (GXLHXEH_BUFINFODATA *)pVal;

#ifdef _LP64
printf(" BuflenUsed: %016x ErrOffset: %016x\n",
pBIVal->XEH_BuflenUsed,pBIVal->XEH_ErrOffset);
#else
printf(" BufLenUsed: %08x ErrOffset: %08x\n",
pBIVal->XEH_BufLenUsed,pBIVal->XEH_ErrOffset);
#endif

printf(" DSOpts: %08x PrsStat: %04x rsv: %04x\n",


pBIVal->XEH_DSOpts,pBIVal->XEH_PrsStat,pBIVal->XEH_BufRsv);

// Display the datastream options.


if (DSOPS(pBIVal))
{ // display any datastream options
printf(" DSOpts: ");
if (DSOPSTRID(pBIVal))
printf("STRINGID ");
if (DSOPSTRCMT(pBIVal))
printf("STRIPCMTS ");
if (DSOPTKWHSP(pBIVal))
printf("TOKWHSP ");
if (DSOPCDCHAR(pBIVal))
printf("CDASCHAR ");
if (DSOPFULEND(pBIVal))
printf("FULLEND ");
if (DSOPVALID(pBIVal))
printf("VALIDATED ");
if (DSOPSRCOFF(pBIVal))

Appendix B. Program source files 229


printf("SOURCEOFFSET");
printf("\n");
} // display any datastream options

// Display the parser status flags.


if (PRSSTAT(pBIVal))
{ // display any parser status flags
printf(" PrsStat: ");
if (PRSUNREF(pBIVal))
printf("UNRESOLVEDREF");
printf("\n");
} // display any parser status flags

return;
} // end of PrintBufInfo

// *************************************************************
// PrintXMLDecl - print record-specific info for XML declarations.
// *************************************************************
void PrintXMLDecl(void *pVal)
{ // start of PrintXMLDecl
GXLHXEH_VALUE *pXDVal; // xml decl values
int fVal = OFF;

pXDVal = (GXLHXEH_VALUE *)pVal;

// The XML declaration record has 3 length/value pairs.


if (VALLEN(pXDVal))
{ // version
printf(" Version: ");
PrintLenVal(pXDVal,0);
fVal = ON;
} // version

pXDVal = NEXTVAL(pXDVal);

if (VALLEN(pXDVal))
{ // encoding
printf(" Encoding: ");
PrintLenVal(pXDVal,0);
fVal = ON;
} // encoding

pXDVal = NEXTVAL(pXDVal);

if (VALLEN(pXDVal))
{ // standalone
printf(" Standalone: ");
PrintLenVal(pXDVal,0);
fVal = ON;
} // standalone

// End the line if any of the XML decl fields were present.
if (fVal)

230 XML Processing Options on z/OS


printf("\n");
return;
} // end of PrintXMLDecl

// *************************************************************
// PrintEAName - print the name values for elements and atributes.
// *************************************************************
void PrintEAName(void *pVal)
{ // start of PrintEAName
GXLHXEH_VALUE *pEANVal; // element name values

pEANVal = (GXLHXEH_VALUE *)pVal;

// The start element has 3 length/value pairs.


if (VALLEN(pEANVal))
{ // Lname
printf(" Lname: ");
PrintLenVal(pEANVal,0);
printf("\n");
} // Lname

pEANVal = NEXTVAL(pEANVal);

if (VALLEN(pEANVal))
{ // NS URI
printf(" NS URI: ");
PrintLenVal(pEANVal,0);
printf("\n");
} // NS URI

pEANVal = NEXTVAL(pEANVal);

if (VALLEN(pEANVal))
{ // NS prefix
printf(" NS prefix: ");
PrintLenVal(pEANVal,0);
printf("\n");
} // NS prefix

return;
} // end of PrintEAName

// *************************************************************
// PrintNSName - print the name values for a namespace.
// *************************************************************
void PrintNSName(void *pVal)
{ // start of PrintNSName
GXLHXEH_VALUE *pNSNVal; // namespace name values

pNSNVal = (GXLHXEH_VALUE *)pVal;

if (VALLEN(pNSNVal))
{ // NS prefix

Appendix B. Program source files 231


printf(" NS prefix: ");
PrintLenVal(pNSNVal,0);
printf("\n");
} // NS prefix

pNSNVal = NEXTVAL(pNSNVal);

if (VALLEN(pNSNVal))
{ // NS URI
printf(" NS URI: ");
PrintLenVal(pNSNVal,0);
printf("\n");
} // NS URI

return;
} // end of PrintNSName

// *************************************************************
// PrintPI - print the target name and value for a processing
// instruction.
// *************************************************************
void PrintPI(void *pVal)
{ // start of PrintPI
GXLHXEH_VALUE *pPIVal; // processing instruction values

pPIVal = (GXLHXEH_VALUE *)pVal;

if (VALLEN(pPIVal))
{ // PI target
printf(" Target: ");
PrintLenVal(pPIVal,0);
printf("\n");
} // PI target

pPIVal = NEXTVAL(pPIVal);

if (VALLEN(pPIVal))
{ // PI value
printf(" Value: ");
PrintLenVal(pPIVal,0);
printf("\n");
} // PI value

return;
} // end of PrintPI

// *************************************************************
// PrintDTD - print the values associated with a DTD.
// *************************************************************
void PrintDTD(void *pVal)
{ // start of PrintDTD
GXLHXEH_VALUE *pXDVal; // DTD values

232 XML Processing Options on z/OS


pXDVal = (GXLHXEH_VALUE *)pVal;

// The DTD has 3 length/value pairs.


if (VALLEN(pXDVal))
{ // root element name
printf(" Root: ");
PrintLenVal(pXDVal,0);
printf("\n");
} // root element name

pXDVal = NEXTVAL(pXDVal);

if (VALLEN(pXDVal))
{ // public identifier
printf(" PUBID: ");
PrintLenVal(pXDVal,0);
printf("\n");
} // public identifier

pXDVal = NEXTVAL(pXDVal);

if (VALLEN(pXDVal))
{ // system identifier
printf(" SYSID: ");
PrintLenVal(pXDVal,0);
printf("\n");
} // system identifier

return;
} // end of PrintEAName

// *************************************************************
// PrintAuxInfo - print the values associated with an auxilliary
// information record.
// *************************************************************
void PrintAuxInfo(void *pVal)
{ // start of PrintAuxInfo
GXLHXEH_AUX_VALUE *pAIVal; // aux info values

pAIVal = (GXLHXEH_AUX_VALUE *)pVal;

// Display the auxinfo flags.


if (AUXFLGS(pAIVal))
{ // display aux info flags
printf(" Flags: ");
if (AUXFLVAL(pAIVal))
printf("LONGVALUE ");
if (AUXFENTY(pAIVal))
printf("ENTITY ");
printf("\n");
} // display aux info flags

// Display the information type.


switch(AUXTYPE(pAIVal))

Appendix B. Program source files 233


{ // information type switch
case GXLHXEC_OFFSET_NULL:
printf(" Type: NULL\n"); break;
case GXLHXEC_OFFSET_START_XMLDECL:
printf(" Type: START XMLDECL\n"); break;
case GXLHXEC_OFFSET_END_XMLDECL:
printf(" Type: END XMLDECL\n"); break;
case GXLHXEC_OFFSET_START_DTD:
printf(" Type: START DTD\n"); break;
case GXLHXEC_OFFSET_END_DTD:
printf(" Type: END DTD\n"); break;
case GXLHXEC_OFFSET_START_STARTTAG:
printf(" Type: START ELEMENT START\n"); break;
case GXLHXEC_OFFSET_END_STARTTAG:
printf(" Type: END ELEMENT START\n"); break;
case GXLHXEC_OFFSET_END_STARTTAGNAME:
printf(" Type: END START NAME\n"); break;
case GXLHXEC_OFFSET_START_ENDTAG:
printf(" Type: START ELEMENT END\n"); break;
case GXLHXEC_OFFSET_END_ENDTAG:
printf(" Type: END ELEMENT END\n"); break;
case GXLHXEC_OFFSET_START_ATTRVALUE:
printf(" Type: START ATTRIBUTE VALUE\n"); break;
case GXLHXEC_OFFSET_END_ATTRVALUE:
printf(" Type: END ATTRIBUTE VALUE\n"); break;
case GXLHXEC_OFFSET_START_COMMENT:
printf(" Type: START COMMENT\n"); break;
case GXLHXEC_OFFSET_END_COMMENT:
printf(" Type: END COMMENT\n"); break;
case GXLHXEC_OFFSET_START_CDATA:
printf(" Type: START CDATA\n"); break;
case GXLHXEC_OFFSET_END_CDATA:
printf(" Type: END CDATA\n"); break;
case GXLHXEC_OFFSET_START_PI:
printf(" Type: START PI\n"); break;
case GXLHXEC_OFFSET_END_PI:
printf(" Type: END PI\n"); break;
case GXLHXEC_OFFSET_START_NSVALUE:
printf(" Type: START NSVALUE\n"); break;
case GXLHXEC_OFFSET_END_NSVALUE:
printf(" Type: END NSVALUE\n"); break;
default:
break;
} // information type switch

// The offset value. This will be either a 4 or an 8 byte


// value, depending on the setting of the long value flag.
if (AUXFLVAL(pAIVal))
{ // 8 byte value
void *pOV = (void *)&(AUXDATA(pAIVal));
long int offsetVal = *(long int *)pOV;
printf(" Value: %d (decimal)\n",offsetVal);
} // 8 byte value

else

234 XML Processing Options on z/OS


{ // 4 byte value
void *pOV = (void *)&(AUXDATA(pAIVal));
int offsetVal = *(int *)pOV;
printf(" Value: %d (decimal)\n",offsetVal);
} // 4 byte value

return;
} // end of PrintAuxInfo

// *************************************************************
// PrintError - print the values associated with an error record
// *************************************************************
void PrintError(void *pVal)

{ // start of PrintError
GXLHXEH_ERRINFODATA *pErrVal; // error values

pErrVal = (GXLHXEH_ERRINFODATA *)pVal;

printf(" Retcode: %08x Rsncode %08x\n",


ERRRC(pErrVal), ERRRSN(pErrVal));

#ifdef _LP64
printf(" Error offset: %016x\n",ERROFFSET(pErrVal));
#else
#ifdef _LONG_LONG
printf(" Error offset: %016x\n",ERROFFSET(pErrVal));
#else
printf(" Error offset: %08x\n",ERROFFSET(pErrVal));
#endif
#endif

return;
} // end of PrintError

// *************************************************************
// PrintLenVal - print the string from a length/value pair in 1
// or more chunks. The number of chunks is
// determined by the width of the output line we
// are using (LINE_WIDTH).
// *************************************************************
void PrintLenVal(GXLHXEH_VALUE *pLV,
int indent)
{ // start of PrintLenVal
char *p = &(VALTEXT(pLV));
int n = VALLEN(pLV);
char blanks[LINE_WIDTH];

// Set up a buffer full of blanks that can be used for indenting


// text.
if (indent)
{ // indent the string
memset(blanks,' ',LINE_WIDTH);

Appendix B. Program source files 235


blanks[indent] = NULLCHAR;
} // indent the string

// Loop through the string to print, and put it out in chunks


// that fit on the screen.
while(n > LINE_WIDTH)
{ // there is chunking to do
int i;
char ch; // char saved for line end

// If there is a null terminator in the string before we get


// to the maximum length of a chunk, print the substring, and
// loop to the next potential chunk.
i = 0;
while((i < LINE_WIDTH) && (p[i] != NEWLINE))
i++;

if (p[i] == NEWLINE)
{ // found a newline
printf("%s%s\n",blanks,p);
i++; // skip past the newline
} // found a newline

else
{ // full chunk encountered
// The strings we are dealing with are not null-terminated.
// We use address and length when dealing with strings.
// This complicates printing, because we have to null-terminate
// each chunk as we print it. Save the character after the end
// of each chunk, replace it with a NULL, and print the chunk.
ch = p[LINE_WIDTH];
p[LINE_WIDTH] = NULLCHAR;
printf("%s%s\n",blanks,p);
p[LINE_WIDTH] = ch;
} // full chunk encountered

// Bump to the next line or chunk.


n -= i;
p += i;
} // there is chunking to do

// Copy the partial chunk to a local buffer and null terminate it


// before trying to print.
if (n > 0)
{ // print a partial chunk
char strChunk[(LINE_WIDTH+1)];

memcpy(strChunk,p,n);
strChunk[n] = NULLCHAR;
if (indent)
printf("%s%s",blanks,strChunk);
else
printf("%s",strChunk);
} // print a partial chunk

} // end of PrintLenVal

236 XML Processing Options on z/OS


Example B-10 shows a sample document that this code was tested against.

Example B-10 Document


<?xml version="1.0" encoding="IBM1047"?>

<person id="JQP">
<name>
<family>John</family>
<given>Public</given>
<middle>Q</middle>
</name>
<phone type="mobile">5555555</phone>
<email>JQP@acmepaperclip.com</email>
</person>

Example B-11 shows the output produced by this example code for the sample XML
document.

Example B-11 Output of the code


----------------------------------------------------------
+0000 BUFFER_INFO - len: 00000020 flags: 00 rsv: 00
BufLenUsed: 000002d0 ErrOffset: 00000000
DSOpts: 28000000 PrsStat: 0000 rsv: 0000
DSOpts: TOKWHSP FULLEND
+0020 XML_DECL - len: 0000001F flags: 00 rsv: 00
Version: 1.0 Encoding: IBM-1047
+003F START_ELEM - len: 0000001A flags: 00 rsv: 00
Lname: person
+0059 ATTR_NAME - len: 00000016 flags: 00 rsv: 00
Lname: id
+006F ATTR_VALUE - len: 0000000F flags: 40 rsv: 00
header flags: NO_ESCAPES
JQP
+007E WHITESPACE - len: 0000000F flags: 40 rsv: 00
header flags: NO_ESCAPES
+008D START_ELEM - len: 00000018 flags: 00 rsv: 00
Lname: name
+00A5 WHITESPACE - len: 00000011 flags: 40 rsv: 00
header flags: NO_ESCAPES
+00B6 START_ELEM - len: 0000001A flags: 00 rsv: 00
Lname: family
+00D0 CHAR_DATA - len: 00000010 flags: 40 rsv: 00
header flags: NO_ESCAPES
John
+00E0 END_ELEM - len: 0000001A flags: 00 rsv: 00
Lname: family
+00FA WHITESPACE - len: 00000011 flags: 40 rsv: 00
header flags: NO_ESCAPES
+010B START_ELEM - len: 00000019 flags: 00 rsv: 00
Lname: given
+0124 CHAR_DATA - len: 00000012 flags: 40 rsv: 00
header flags: NO_ESCAPES
Public
+0136 END_ELEM - len: 00000019 flags: 00 rsv: 00

Appendix B. Program source files 237


Lname: given
+014F WHITESPACE - len: 00000011 flags: 40 rsv: 00
header flags: NO_ESCAPES
+0160 START_ELEM - len: 0000001A flags: 00 rsv: 00
Lname: middle
+017A CHAR_DATA - len: 0000000D flags: 40 rsv: 00
header flags: NO_ESCAPES
Q
+0187 END_ELEM - len: 0000001A flags: 00 rsv: 00
Lname: middle
+01A1 WHITESPACE - len: 0000000F flags: 40 rsv: 00
header flags: NO_ESCAPES
+01B0 END_ELEM - len: 00000018 flags: 00 rsv: 00
Lname: name
+01C8 WHITESPACE - len: 0000000F flags: 40 rsv: 00
header flags: NO_ESCAPES
+01D7 START_ELEM - len: 00000019 flags: 00 rsv: 00
Lname: phone
+01F0 ATTR_NAME - len: 00000018 flags: 00 rsv: 00
Lname: type
+0208 ATTR_VALUE - len: 00000012 flags: 40 rsv: 00
header flags: NO_ESCAPES
mobile
+021A CHAR_DATA - len: 00000014 flags: 40 rsv: 00
header flags: NO_ESCAPES
555-5555
+022E END_ELEM - len: 00000019 flags: 00 rsv: 00
Lname: phone
+0247 WHITESPACE - len: 0000000F flags: 40 rsv: 00
header flags: NO_ESCAPES
+0256 START_ELEM - len: 00000019 flags: 00 rsv: 00
Lname: email
+026F CHAR_DATA - len: 00000021 flags: 40 rsv: 00
header flags: NO_ESCAPES
JQP@acmepaperclip.com
+0290 END_ELEM - len: 00000019 flags: 00 rsv: 00
Lname: email
+02A9 WHITESPACE - len: 0000000D flags: 40 rsv: 00
header flags: NO_ESCAPES
+02B6 END_ELEM - len: 0000001A flags: 00 rsv: 00
Lname: person

----------------------------------------------------------

238 XML Processing Options on z/OS


C

Appendix C. Additional material


This book refers to additional material that can be downloaded from the Internet as described
below.

Locating the Web material


The Web material associated with this book is available in softcopy on the Internet from the
IBM Redbooks Web server. Point your Web browser at:
ftp://www.redbooks.ibm.com/redbooks/SG247810

Alternatively, you can go to the IBM Redbooks Web site at:


ibm.com/redbooks

Select the Additional materials and open the directory that corresponds with the IBM
Redbooks form number, SG247810.

Using the Web material


The additional Web material that accompanies this book includes the following files:
File name Description
7810code.zip Zipped Code Samples

System requirements for downloading the Web material


The following system configuration is recommended:
Hard disk space: 1 MB
Operating System: Windows/Linux

© Copyright IBM Corp. 2009. All rights reserved. 239


How to use the Web material
Create a subdirectory (folder) on your workstation, and unzip the contents of the Web
material zip file into this folder.

240 XML Processing Options on z/OS


Abbreviations and acronyms
ASCII American Standard Code for zAAP System z Application Assist
Information Interchange Processor
BOM Byte Order Mark zIIP System z Integrated Information
CICS Customer Information Control Processor
System ASCII American Standard Code for
CSS Cascading Style Sheet Information Interchange

DOM Document Object Model BOM Byte Order Mark

DTD Data Type Definition CICS Customer Information Control


System
EBCDIC Extended Binary Coded Decimal
Interchange Code CSS Cascading Style Sheet

ESB Enterprice Service Bus DOM Document Object Model

ESDS VSAM Entry Sequenced Data Set DTD Data Type Definition

GDG Generation Data Group EBCDIC Extended Binary Coded Decimal


Interchange Code
HFS z/OS UNIX Hierarchial File System
ESB Enterprice Service Bus
HTML Hyper Text Markup Language
ESDS VSAM Entry Sequenced Data Set
IBM International Business Machines
Corporation GDG Generation Data Group

ITSO International Technical Support HFS z/OS UNIX Hierarchial File System
Organization HTML Hyper Text Markup Language
KSDS VSAM Key Sequenced Data Set IBM International Business Machines
OSR Optimized Schema Representation Corporation

PDS Partitioned Data Set ITSO International Technical Support


Organization
PDSE Partitoned Data Set Extended
KSDS VSAM Key Sequenced Data Set
RRDS VSAM Relative Record Data Set
OSR Optimized Schema Representation
SAX Simple API for XML
PDS Partitioned Data Set
SGML Standard Generalized Markup
Language PDSE Partitoned Data Set Extended

SOAP Simple Object Access Protocol RRDS VSAM Relative Record Data Set

UTF Unicode Transformation Format SAX Simple API for XML

VSAM Virtual Storage Access Method SGML Standard Generalized Markup


Language
WAS WebSphere Application Server
SOAP Simple Object Access Protocol
XLL XML Linking Language
UTF Unicode Transformation Format
XML Extensible Markup Language
VSAM Virtual Storage Access Method
XPATH XML Path Language
WAS WebSphere Application Server
XPLINK eXtra Performance Linkage
XLL XML Linking Language
XPointer XML Pointer Language
XQuery XML Query Language
XSD XML Schema Definition
XSL eXtensible Stylesheet Language
XSLT eXtensible Stylesheet Language
Transformation
z/FS z/OS UNIX File System

© Copyright IBM Corp. 2009. All rights reserved. 241


242 XML Processing Options on z/OS
Glossary

Schema XML Schema is used to define, describe and


catalogue XML vocabularies for classes of XML
documents

URI Uniform Resource Identifier is used to name a


resource on the Internet. Often used within XML to
reference schema documents.

IRI Internationalized Resource Identifier is used to


name (with non ASCII characters) a resource on the
Internet. See URI.

Language Environment Conforming adheres to


Language Environment’s common interface.

Language Environment Compliant does not use


Language Environment services but does not damage or
interfere with Language Environment’s run-time
environment.

xsd. XML schema document. Also called schema or XML


schema.

© Copyright IBM Corp. 2009. All rights reserved. 243


244 XML Processing Options on z/OS
Related publications

The publications listed in this section are considered particularly suitable for a more detailed
discussion of the topics covered in this book.

IBM Redbooks
For information about ordering these publications, see “How to get Redbooks” on page 246.
Note that some of the documents referenced here might be available in softcopy only.

Other publications
These publications are also relevant as further information sources:

XML
򐂰 z/OS XML System Services User’s Guide and Reference, SA23-1350
򐂰 XML Toolkit for z/OS User’s Guide, SA22-7932

DB2
򐂰 DB2 Version 9.1 for z/OS Application Programming and SQL Guide, SC18-9841
򐂰 DB2 Version 9.1 for z/OS SQL Reference, SC18-9854
򐂰 DB2 Version 9.1 for z/OS Internationalization Guide, SC19-1161

COBOL
򐂰 XML System Service parser in Enterprise COBOL for z/OS Version 4.2 Compiler and
Runtime Migration Guide, GC23-8527
򐂰 Enterprise COBOL for z/OS, Language Reference Version 4 Release 1, SC23-8528
򐂰 Enterprise COBOL for z/OS Programming Guide V4R1, SC23-8529
򐂰 DB2 9 pureXML Guide, SG24-7315
򐂰 DB2 9: pureXML Overview and Fast Start, SG24-7298

PL/I
򐂰 Enterprise PL/I for z/OS Programming Guide, SC27-1457

WebSphere MQ
򐂰 WebSphere MQ Intercommunication, Version 6.0, SC34-6587
򐂰 WebSphere MQ Application Programming Reference Version 6.0, SC34-6596

z/OS topics
򐂰 z/OS Support for Unicode: Using Unicode Services, SA22-7649
򐂰 z/OS Metal C Programming Guide and Reference, SA23-2225
򐂰 z/OS MVS Programming: Assembler Services Guide, SA22-7605
򐂰 z/OS V1R11.0 UNIX System Services Planning, GA22-7800
򐂰 z/OS V1R11.0 Language Environment Programming Reference, SA22-7562
򐂰 z/OS V1R11.0 UNIX System Services Command Reference, SA22-7802

© Copyright IBM Corp. 2009. All rights reserved. 245


Online resources
These Web sites are also relevant as further information sources:

How to get Redbooks


You can search for, view, or download Redbooks, Redpapers, Technotes, draft publications
and Additional materials, as well as order hardcopy Redbooks publications, at this Web site:
ibm.com/redbooks

Help from IBM


IBM Support and downloads
ibm.com/support

IBM Global Services


ibm.com/services

246 XML Processing Options on z/OS


Index
coded character set ID 146
Symbols EBCDIC 147
iconv() 149
__IBM_METAL__ 125 Unicode 147
_BPX_AUTOCVT 161 child node
_BPXK_CCSIDS 161 oldChild 104
.profile 115 chtag 162
/usr/include/metal 123 CICS 20, 26, 28, 31, 35, 38
CICS transaction 35, 107
A werver 20, 161
acceptable codepages 139 CICS TS 20, 28, 38
American Standard Code for Information Interchange 3.2 140
(ASCII) 146 4.1 20, 29, 38–39, 109, 141
application program 27, 70, 79, 86, 107, 160 CICS Web Service 20, 38, 57, 106–107, 140
application programming interface (API) 10, 23, 67, 86, CICS Web Services Assistant 58, 107
100 COBOL 16–17, 21, 27, 86, 139–140, 149–150
application startup 26 generating 42
assembler 27, 35, 67, 88, 142 COBOL application 86, 106, 140
assembler interface 137 COBOL XML
attribute-style 44 PARSE 82
author country 103 CODEPAGE 149, 165
automatic conversion 139, 154 COMMAREA 161
Comp-5 Value 0 189
complete list 123, 139, 148
B CSSLIB 132
bare metal C CUNLCNV 48
code variant 88 CVT 132
environment 123
BASE64 60
basic XML D
definition 8 data stream 16, 67, 94, 117, 119, 149
document information 183 DB2 22, 26–28, 33, 35, 39
BI (business intelligence) 138 DB2 9 22, 39, 82, 110
big endian pureXML 22
format 156 DB2 database 160
binary zero 9 DB2 XML functions
body bgcolor 12 XML2CLOB 60
built-in function XMLAGG 60–61
XMLCHAR 151 XMLATTRIBUTE 60
Business Processing Execution Language (BPEL) 33 XMLATTRIBUTES 63
byte-order-mark (BOM) 80, 147, 185 XMLCOMMENT 60
XMLCONCAT 60, 62
XMLDOCUMENT 60
C XMLELEMENT 60, 62–63
C 27, 88–89, 141 XMLFOREST 60
C/C++ language binding 66, 133 XMLNAMESPACE 60
C++ 27, 88–89, 141 XMLPI 60
carriage return (CR) 8, 147 XMLQUERY 60
CCSID 146, 157, 161, 167 XMLSERIALIZE 60–61
char b 176 XMLTEXT 60
character 146 DD DISP 115
ASCII 146 DD name
character encoding 146 OUTDATA 186
character set 146 TSTXML 186
coded character set 146 Document Object Model (DOM) 10–11, 27

© Copyright IBM Corp. 2009. All rights reserved. 247


document type gxl1prs entry 168
definition 2, 188 GXL1QXD service 153, 180
document validation 16, 86, 95 GXLESTRI 122–123
DOM parsing 102
DOM tree 11, 80, 102–103
DSA 125 H
DTD 2 Hans-Dieter Mertiens 103
Dynamic Stack Area (DSA) 123 header flag 224
heterogeneous system 148, 158
Hierarchical File System (HFS) 26, 100, 147
E HTML page 12
EBCDIC code HTTP 158
page 148 HTTP header 158
element name 4, 6, 70, 109, 128 encoding declarations 158
ELEMENT TELEFONO2 3 meta charset declaration 158
element-style 42 Hyphes in element names 46
enclave 88
encoding 7, 139
Enterprise 81 I
enterprise COBOL 17–18, 38, 81, 86, 106, 117, 149, 180 IANA 161
Parsing architecture 18 IBMZCBG 133
program 183 IMS 21, 26, 28, 31, 34
V3R1 18 IMS data 34
V4 18 IMS database 21, 34
V4R1 17 input buffer 68–69, 119, 167
XML System Service parser 91 Input-Buffer-Length XML-Doc-Len 199
enterprise PL/I 19, 38, 81, 87, 138, 151 int argc 176
Enterprise Service Bus (ESB) 22, 26, 32 internal DTD 2, 79
ENVAR 115 ENTITY attribute 79
epilog 125 invalid XML 136
ESB 31 document 136
ESDS 26 structure 2
EXEC SQL ISO-10646 45
Call 31
UPDATE tbl SET xml_col 83 J
existing language structure J2EE 31
WSDL document 107 Java 22, 143
Extended Binary Coded Decimal Interchange Code Java Messaging System (JMS) 33
(EBCDIC) 147 JMS See messaging
external DTD 2 JOBPARM SYSAFF 114

F K
FD TstXML 188 KSDS 26
fetch 126
file transfer protocol (FTP) 26, 152
FILETAG 161 L
language binding 68, 131, 133
Language Environment 66, 88, 122
G binding 142
GDG 26, 28 run-time dependancy 122
generating language structure 106
COBOL 38, 42, 45 left-over byte 71
PL/I 19, 38, 48 line feed (LF) 8, 147
Generating COBOL 81 Linux 23
GET CONTAINER 161
GROUP-USAGE National 149
gxl_lvpairs 117, 169 M
gxl_valchs 169 MEMCONVERT 48, 165
gxl_vallen 117, 169 message queue (MQ) 29
gxl1ini entry 132, 167 message queue interface (MQI) 33

248 XML Processing Options on z/OS


message transmission optimization mechanism (MTOM) P
20 parsed data
messaging 26, 31, 35 stream 67, 69, 94, 119
Metal C 122 parser instance memory area (PIMA) 66, 161
conversion 123 parsing 95
environment 123 COBOL 18, 81, 89–91, 149
version 122 COBOL with validation 82
MOVE 1 195 PL/I 16, 19, 81, 87, 89–91, 140
move function 200 parsing and validation with XML Toolkit 78
Move GXL1PRS-Reason-Code 193 Parsing COBOL 38
Move GXL1PRS-Return-Code 193 parsing PL/I 19, 38
move space 192 parsing with XML Toolkit for z/OS 76
move zero 192 partitioned data set extended (PDSE) 114
MQ message 18, 90 PDS 26
MQ message broker 32 PDSE 26
MQ Messaging see messaging PIC N 149
MQ queue PIMA length 132, 167
manager 159 PL/I 27, 139, 151
reading program 35 application 19, 87, 106, 140
MQ See messaging example 117
MQ server 158 generating 48
MTOM 22 program 66, 117, 119
multiple buffer 66 Call gxlini 132
mutable field 119, 171 complete listing 119
MVS 100 pointer byaddr 132, 167
pointer byvalue 132, 167
N POSIX(ON) 115
name space pragma runopts 134, 176
prefix 81 predefined String IDs 99
namespace declaration 5, 67 process server 22, 26, 32
xmlns keyword 6 processing instruction (PI) 5, 80, 101
namespace URI 105 programming language 2, 15, 27, 99, 154
namespaces 6 PTFs UA40707 137
native Java 22 pureXML 33
newline 148, 223 PUT CONTAINER 161
non-validating parse 94, 99
non-validating parsing Q
basic approaches 94 QXD Version 153, 182
non-XPLINK
environment 136
version 100, 136 R
NS prefix 231 Rational Developer for System z 21
NS URI 231 Read TstXML 182
reason code 68–70, 119, 132, 157, 167, 180
Redbooks Web site 246
O Contact us xix
OCOPY 162 return code 68, 70, 119, 132, 157, 167
OGET 162 REXX 67
OGETX 162 routines PLISAXA 81, 151
optimized schema representation (OSR) 75, 82, 95, 98, RRDS 26
114, 176–177 rsn 117, 175
OPUT 162 rsv 226
OPUTX 162
original XML
document 33–34 S
form 33 sample useLang 152
string 33 SAMPLIB 122
OSR generation 96 SAX 10, 27
output buffer 68, 70, 86, 119, 168 Schema 4
minimum size 70 schema URLs 5

Index 249
Select OutData 188 UNIX HFS 26
Select TstXML 180 UNIX z/FS 26
service request block (SRB) 66, 88 USAGE National 149
Simple API for XML (SAX) 10 user-defined functions (UDF) 31
SO-10646 46 UTF scheme 147
SOAP 22, 31 UTF-16BE 148
sparse parsing 95 UTF-8 148
SQL guide 83, 111
SQL Type
host variable 83 V
SQL type 83 valid XML 110
SRB 88 document 152
mode 22, 138 stream 17
Standard Generalized Markup Language (SGML) 2 string 21
Standard OS Linkage 132 validate 136
static init 167 validating parsing 97
String IDs validation 9, 110, 136
Non-validating parsing 94 validation COBOL 82
string IDs 76, 94, 98, 127 value space 181
String Message-Level 210 virtual DOMNode 104
StringID 75, 94–95, 97–98, 122 virtual void
StringID Table 76, 94, 130 endDocument 101
StringID value 95 endElement 101
StringIDHandler 75 ignorableWhitespace 101
StringIDTable 122, 176 processingInstruction 101
Supervisory Control And Data Acquisition (SCADA) 33 release 106
SYS1.CSSL IB 132, 180 resetDocument 101
SYS1.SAMPLIB 128 setDocumentLocator 102
SYSLIB 132 setNodeValue 105
SYSOUT 26 setPrefix 105
system services parameter area 75 setTextContent 105
system services vector 125 startDocument 102
System z 15, 25, 88–89, 145, 147–148 startElement 102
common exit points 26 VSAM
DB2 V8 35 ESDS 26
extensible means 88 KSDS 26
Linux 23 RRDS 26
preferred encoding 148
Rational Developer 21 W
WebSphere MQ Messaging 35 Web Service 38
XML documents 160 Web service 26, 28, 38, 160
XML processing 16 Web site 23, 239
XML-enabled products 16 WebSphere Application Server 22, 31
WebSphere Enterprise Service Bus 22, 32
T WebSphere ESB 32
tag name 69 WebSphere Message Broker 22, 26
task control block (TCB) 88 WebSphere MQ
toolkit 76, 88, 136, 147 application 158
toolkit parser 16 Intercommunication 159
transform statement (TS) 20, 28, 109 Messaging 35
transformation 16–17, 80, 88–89 WebSphere MQ Message Broker 32
XML to record 88 WebSphere MQ See messaging
XML to XML 88 WebSphere Process Server 22, 32
transforming 89 well-formed 9
whitespace 147, 188
carriage return 147
U horizontal tabulation 147
Unicode service 149 line feed 147
Unicode Transformation Format (UTF) 146 NEL 147
UNIX environment 100 newline 147

250 XML Processing Options on z/OS


whole document 90 XML processing
Windows Notepad 154 eligible 138
dialog box 154 model 27
file 156 requirement 21–22
WSBind 58, 107 XML release 153, 182
wsbind file 107 XML sample 6
XML Schema
Language 5
X validation 16
XEH_DSOpts 224 XML schema 4, 16, 21, 34, 109, 111
Xerces 16 definition 5, 38, 75, 95
XLC 123 namespace 5
XML 1–2, 17, 25, 37, 65, 86, 93, 145, 165 option 5
XML 1.1 8, 147 XML schema definition (XSD) 4–5, 95, 114
current version 8 element name 4
second edition 8 file 75, 95, 114
XML column 83, 160 XML standard 2
XML converter 21, 30 XML stream 17, 66, 110, 149
XML data 21, 26, 33, 67, 83, 151 XML string 9, 21, 37, 66, 75, 95, 109, 116, 165
primary use 21 basic information 121
XML declaration 7–8, 67, 151, 230 buffer window 68
encoding attribute 151 String IDs 98
record-specific info 230 XML Stylesheet Language (XSL) 11
specified CCSID 153 XML System Service 16, 66, 86, 94, 117, 137
XML document 2, 16, 26, 39, 67, 73, 95, 102, 104, 120, XML to record 88
122, 135, 145, 148, 168, 180, 187 XML to XML 88
basic rules 9 XML Toolkit 16, 39, 76, 88–90, 99, 136, 148
character data 187 glue code 18
declaration 5 other considerations 79
different encoding schemes 145 Parser 16, 27, 90
encoding declaration 149 source offsets 79
event 18 unique aspect 16
file 26 XSLT Processor 17, 27, 39, 88
first bytes 8 XML Toolkit Parser, C++ Edition 16
HTML document 12 XML Toolkit XSLT Processor, C++ Edition 16
needed information 103 XML Transformation 11
Other products deal 23 XML version 2, 103, 120, 152, 182
root element 5 XML4C 16
text 87 XML-binary optimization Packaging (XOP) 20
validation 10 XMLCHAR 48
XML elements 11 XMLPARSE 18, 86, 106, 149
xml document XOP 22
length 168 XPath 11, 60
XML element XPLINK 100, 133, 136
declaration 80 XPLink 79, 88, 136
XML example 165 Xpointer 11
XML flag 152 XQuery 11
XML GENERATE 45 xsdosrg 122
XML generation 17, 66, 89 XSL 11
built-in function 19 XSLT 11
capability 21 XSLT Processor 80, 88, 136
code 22
XML input
string 139 Z
XML message 29, 107, 159 z/FS 26
XML parse 18, 66, 81, 86, 98, 106 z/OS specific parser class 76, 99
RETURNING NATIONAL clause 81 z/OS System Services
XML parser 9, 66, 86, 100, 136, 147 GXL1IDI 128
XML parsing PIMA 73
built-in Java classes 143 z/OS UNIX 8, 22, 26, 66, 110, 114–115, 152, 161, 183
direct support 16 batch interface routine 114

Index 251
command line 122
environment 115, 154
file system 152
shell 114
z/OS user 18, 90, 245
z/OS V1.9 137
IBM XML Toolkit 137
XML Toolkit 137
z/OS V3R3 17, 38
Enterprise COBOL 17
Enterprise PL/I 19
z/OS V4R2 18, 82
z/OS XML 16, 66, 137, 180
data stream 223
parse record stream 224
parser 66, 91, 187, 202
System Services 16, 27, 66, 86–88, 90–91, 94–95,
110, 113–114, 133, 137, 147–148, 163, 186–187, 245
GXL1INI 73
GXL1PRS 70, 73
GXL1QXD 149, 152
GXL4QXD 149, 152
gxluGenOSR 75
GXLYQXD 152
key benefit 68
PIMA 66, 70, 73
System Services assembler interface 88
System Services C 88
System Services C/C++ APIs 79
System Services combination 86
System Services non-validating parsing 137
System Services parse 75
System Services parser 18, 69, 86, 90, 95, 117, 202
System Services reason code
x1301 69–70, 119, 175
x1302 70
x1303 69–70, 119, 175
x1304 69, 71, 119, 175
System Services return code
x1302 70
System Services routine gxlprs 68
System Services user 70, 149
System Services user guide 152
Toolkit 39, 76, 88, 99, 136, 148
Toolkit XSLT processor 18
See also XML Toolkit
zAAP 16, 31, 68, 76, 86, 91, 137
zAAP processor 21, 138
CPU cost 140
zIIP 68, 91, 137
zIIP processor 22, 138
zAAP-eligible work 138

252 XML Processing Options on z/OS


XML Processing Options on z/OS
XML Processing Options on z/OS
XML Processing Options on z/OS
(0.5” spine)
0.475”<->0.873”
250 <-> 459 pages
XML Processing Options on z/OS
XML Processing Options on z/OS
XML Processing Options on z/OS
Back cover ®

XML Processing on z/OS

Overview of XML XML plays an increasingly important part in today’s business


automation systems. Service-oriented architecture (SOA), enterprise INTERNATIONAL
generation and
service bus (ESB) and other modern architectures all build upon XML. TECHNICAL
parsing technologies
Each year more industries migrate their data-exchange applications to SUPPORT
available on z/OS XML and XML-based formats. XML continues to be one of the most ORGANIZATION
pervasive and successful technologies for the new millennium.
Code samples for
This IBM Redbooks publication presents a broad perspective of the
z/OS XML Systems XML processing capabilities of z/OS . It begins with a high level view of
Services and Toolkit IBM products currently implementing XML-specific features. It covers
common design patterns and the products that use them. It provides BUILDING TECHNICAL
XML features for in-depth coverage of the two primary XML activities: INFORMATION BASED ON
PRACTICAL EXPERIENCE
COBOL, PL/I, DB2 򐂰 Generating valid XML
pureXML, and CICS 򐂰 Parsing XML IBM Redbooks are developed
It discusses where and how XML data can be stored. The book focuses by the IBM International
on z/OS and non-Java technologies and products, since there are other Technical Support
materials available on the Java side. Java support is largely Organization. Experts from
cross-platform and not specific to z/OS.
IBM, Customers and Partners
from around the world create
The authors have included examples of simple and complex timely technical information
procedures, all of which have been tested. They have included based on realistic scenarios.
cautions and alternatives for common issues and pitfalls. Specific recommendations
are provided to help you
This book is helpful to anyone trying to learn about the various IBM implement IT solutions more
products that provide XML-oriented services and how they fit into effectively in your
existing applications. It is also valuable to developers needing to gauge environment.
the pros and cons of the ways of generating and consuming XML. It
provides working examples to those needing a fast path to coding XML
applications.
For more information:
ibm.com/redbooks

SG24-7810-00 0738433780

You might also like