278
ibm.com/redbooks Front cover XML Processing on z/OS Mike Ebbers Mogens Conrad Hans-Dieter Mertiens Nagesh Subrahmanyam Michael Todd 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

XML Processing on zOS

Embed Size (px)

Citation preview

Page 1: XML Processing on zOS

ibm.com/redbooks

Front cover

XML Processing on z/OS

Mike EbbersMogens Conrad

Hans-Dieter MertiensNagesh Subrahmanyam

Michael Todd

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

Page 2: XML Processing on zOS
Page 3: XML Processing on zOS

International Technical Support Organization

XML Processing Options on z/OS

December 2009

SG24-7810-00

Page 4: XML Processing on zOS

© 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 ScheduleContract with IBM Corp.

First Edition (December 2009)

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

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

Page 5: XML Processing on zOS

Contents

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

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

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

Notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xvTrademarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvi

Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviiThe team who wrote this book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviiBecome a published author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xixComments welcome. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix

Chapter 1. XML essentials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.1 Introduction to XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.1.1 DTD. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.2 XML schema definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

1.2.1 XML schema options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.2.2 xsd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

1.3 Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61.4 Encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.5 XML 1.0 and XML 1.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81.6 XML processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

1.6.1 Well-formedness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91.6.2 Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

1.7 Industry formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101.8 XML parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

1.8.1 SAX: Simple API for XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101.8.2 DOM: Document Object Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111.8.3 Less common parsing methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

1.9 XML Transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

Chapter 2. Overview of XML processing on System z. . . . . . . . . . . . . . . . . . . . . . . . . . 152.1 z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162.2 XML Toolkit for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162.3 Enterprise COBOL for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

2.3.1 COBOL XML generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172.3.2 COBOL XML parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

2.4 Enterprise PL/I for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192.4.1 PL/I XML generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192.4.2 PL/I XML parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

2.5 CICS Transaction Server for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202.6 IMS XML DB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212.7 Rational Developer for System z. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212.8 Java-centric processing of XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.9 pureXML on DB2 9 for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.10 Linux for System z. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

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

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

Page 6: XML Processing on zOS

3.1 Common points of Entry and Exit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263.1.1 XML documents as files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263.1.2 Messaging transports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263.1.3 Web services through HTTP/SOAP requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263.1.4 Generated and consumed on z. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

3.2 XML processing models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273.2.1 File triggered batch jobs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273.2.2 Scheduled batch jobs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283.2.3 Web services and DB2, IMS, CICS TS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283.2.4 WebSphere Application Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313.2.5 Enterprise Service Bus, MQ Message Broker, Process Server . . . . . . . . . . . . . . 323.2.6 DB2 as an XML warehouse and middle tier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333.2.7 IMS as an XML warehouse and middle tier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343.2.8 Messaging interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

Chapter 4. Overview of XML generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374.1 Enterprise COBOL for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384.2 Enterprise PL/I for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384.3 4.3 CICS TS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384.4 Web Services in CICS TS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384.5 XML Toolkit for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394.6 DB2 for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

Chapter 5. How to generate XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415.1 Generating XML from COBOL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

5.1.1 COBOL XML GENERATE examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425.1.2 XML GENERATE error handling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455.1.3 COBOL reserved words as element and attribute names. . . . . . . . . . . . . . . . . . . 465.1.4 Hyphens in element names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465.1.5 Upper-case element names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465.1.6 COBOL data attributes that suppress XML string generation. . . . . . . . . . . . . . . . 475.1.7 Multi-byte character encoding. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

5.2 Generating XML from PL/I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485.3 XML Toolkit for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495.4 Generating XML from CICS Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

5.4.1 CICS Web Services Assistant. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585.5 CICS Transform statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595.6 DB2 for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

Chapter 6. Overview of parsing technologies on z/OS . . . . . . . . . . . . . . . . . . . . . . . . . 656.1 z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

6.1.1 Parsed XML data stream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 676.1.2 Programming interface provided by XML System Services . . . . . . . . . . . . . . . . . 686.1.3 Buffer handling with XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 686.1.4 General scheme for invoking z/OS XML System Services for parsing . . . . . . . . . 706.1.5 Optimized schema representation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 756.1.6 Concept of StringID. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

6.2 XML Toolkit on z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 766.2.1 Parsing with XML Toolkit for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 766.2.2 Parsing and validation with XML Toolkit on z/OS . . . . . . . . . . . . . . . . . . . . . . . . . 786.2.3 Parsing and source offsets with XML Toolkit on z/OS . . . . . . . . . . . . . . . . . . . . . 79

6.3 Transforming XML documents with XML Toolkit for z/OS. . . . . . . . . . . . . . . . . . . . . . . 806.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

Page 7: XML Processing on zOS

6.4.2 Enterprise COBOL for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 816.5 Parsing with pureXML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 826.6 Storing XML within DB2 for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

Chapter 7. Processing components, relationships, and options . . . . . . . . . . . . . . . . . 857.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 . . . . . 867.1.2 Enterprise PL/I for z/OS programs and XML System Services on z/OS. . . . . . . . 877.1.3 Assembler, C, and XML System Services on z/OS . . . . . . . . . . . . . . . . . . . . . . . 887.1.4 C++ and z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 887.1.5 Software outside the usual scope of a TCB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

7.2 When to use the XML Toolkit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 887.2.1 XML document transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 887.2.2 Implementing C or C++ applications using XML parser classes. . . . . . . . . . . . . . 897.2.3 Invoking the XML Toolkit XSLT Processor from within COBOL-PL/I

applications. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 897.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 . . . . . . . . . . . . . . . . . . . . . . . . . 907.3.1 When to use the z/OS XML System Services parser . . . . . . . . . . . . . . . . . . . . . . 907.3.2 When to use the COBOL native parser. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 917.3.3 When to use the z/OS XML parser rather than the PL/I native parser . . . . . . . . . 917.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. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 938.1 Parsing Using z/OS XML System Services. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

8.1.1 Non-validating Parsing using z/OS XML System Services . . . . . . . . . . . . . . . . . . 948.1.2 Validating parsing using z/OS XML System Services. . . . . . . . . . . . . . . . . . . . . . 95

8.2 XML Toolkit for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 998.2.1 SAX parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1008.2.2 DOM parsing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

8.3 COBOL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1068.4 PL/I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1068.5 CICS Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

8.5.1 CICS Web Services Assistant. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1078.6 CICS Transform statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1098.7 Parsing with pureXML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110

8.7.1 Simple DB2 parsing without validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1108.7.2 Simple DB2 parsing with validation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110

Chapter 9. Hints, tips, and samples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1139.1 Validation using optimized schema representation (OSR) . . . . . . . . . . . . . . . . . . . . . 114

9.1.1 Creating an OSR. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1149.1.2 Parse with validation: Using the OSR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1169.1.3 Basic flow of a program to handle parsed data. . . . . . . . . . . . . . . . . . . . . . . . . . 1179.1.4 Basic loop to manage the input and output buffer . . . . . . . . . . . . . . . . . . . . . . . 1199.1.5 Detailed view at the parsed data stream. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1209.1.6 Get a StringID exit working . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1229.1.7 Extracting a StringID Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130

9.2 Using the language bindings. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1319.2.1 Assembler interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1329.2.2 C/C++ language bindings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133

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

Contents v

Page 8: XML Processing on zOS

10.1 Where and when to validate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13610.2 XPLINK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136

10.2.1 XML Toolkit for z/OS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13610.2.2 z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13710.2.3 COBOL and PL/I built-in parsers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137

10.3 zIIPs and zAAPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13710.3.1 zAAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13710.3.2 zIIP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13810.3.3 zAAP on zIIP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138

10.4 Encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13910.4.1 XML Toolkit for z/OS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13910.4.2 z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13910.4.3 COBOL and PL/I built-in parsers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

10.5 Application language. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13910.5.1 COBOL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14010.5.2 PL/I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14010.5.3 C and C++. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14110.5.4 Assembler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14210.5.5 Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143

Chapter 11. XML and character encoding issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14511.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146

11.1.1 Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14611.2 UTF schemes and System z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147

11.2.1 Advantages of using Unicode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14811.2.2 Character encoding schemes supported on System z . . . . . . . . . . . . . . . . . . . 14811.2.3 z/OS XML Toolkit and z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . 14811.2.4 Enterprise COBOL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14911.2.5 Enterprise PL/I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151

11.3 Encoding examples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15211.3.1 EBCDIC XML document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15211.3.2 UTF-8 XML document. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15411.3.3 UTF-16BE XML document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15611.3.4 UTF-16LE XML document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

11.4 Exchanging XML documents between heterogeneous systems. . . . . . . . . . . . . . . . 15811.4.1 HTTP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15811.4.2 WebSphere MQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15811.4.3 FTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16011.4.4 DB2 database and encoding considerations . . . . . . . . . . . . . . . . . . . . . . . . . . 16011.4.5 CICS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16111.4.6 Saving ASCII files on System z. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

Appendix A. Supported character encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163Supported code pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164

Appendix B. Program source files. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165B.1 PL/I example to generate XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165B.2 PL/I program to call z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167B.3 C program to extract the StringIDTable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176B.4 Enterprise COBOL program to query XML document declaration . . . . . . . . . . . . . . . 180B.5 C program to query XML document declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183B.6 Enterprise COBOL program to invoke z/OS XML System Services parser without

validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186B.7 Enterprise COBOL program to invoke z/OS XML System Services parser with a string ID

vi XML Processing Options on z/OS

Page 9: XML Processing on zOS

exit (without validation) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202B.8 C program to traverse a z/OS XML parsed record stream

and display the information in it . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223

Appendix C. Additional material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239Locating the Web material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239Using the Web material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239

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

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

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

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

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

Contents vii

Page 10: XML Processing on zOS

viii XML Processing Options on z/OS

Page 11: XML Processing on zOS

Figures

1-1 XML from Example 1-1 on page 2 transformed to HTML using XSLT stylesheet. . . . . 132-1 XML Toolkit for z/OS architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172-2 Parsing architecture for Enterprise COBOL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182-3 PL/I and z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192-4 CICS Transaction Server XML architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202-5 IMS DB XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212-6 DB2 with pureXML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233-1 CICS TS and XML/SOAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283-2 CICS transform statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293-3 IMS Web Services connectivity solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303-4 IMS and Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303-5 DB2 as a Web services provider. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313-6 DB2 as a Web services consumer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313-7 WebSphere Application Server and SOAP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323-8 Enterprise Service Bus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323-9 DB2 as an XML warehouse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333-10 IMS as a middle tier or warehouse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343-11 IMS as a Java/XML application server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343-12 MQ messaging triggered listener applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354-1 CICS as a service requester . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385-1 HTML result from XSLT transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525-2 CICS as Web services requester . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 575-3 CICS Web Services Assistant. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586-1 z/OS XML System Services parsed data stream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 676-2 Buffers usages and flow in XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . 696-3 Flowchart for invoking z/OS XML System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . 726-4 One way of invoking z/OS XML System Services parser in case of x’1302’ reason code

746-5 String ID exit processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 766-6 Flow of parsing with existing parsers (top) and z/OS-specific parsers (bottom) . . . . . . 776-7 Validating parse with z/OS-specific classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 787-1 COBOL and z/OS XML System Services combinations . . . . . . . . . . . . . . . . . . . . . . . . 867-2 PL/I and z/OS XML System Services combinations . . . . . . . . . . . . . . . . . . . . . . . . . . . 877-3 Invoking the XML toolkit from within COBOL-PL/I, single document input . . . . . . . . . . 897-4 Invoking the XML Toolkit from within COBOL-PL/I for multiple input documents . . . . . 897-5 Invoking the XML toolkit from within COBOL-PL/I for a single output document . . . . . 908-1 Simple non-validating parsing using z/OS XML System Services . . . . . . . . . . . . . . . . 948-2 Non-validating parsing with z/OS XML System Services using String IDs . . . . . . . . . . 948-3 Non-validating z/OS XML System Services parsing with a predefined set of String ID

values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 958-4 Two-step validating parse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 968-5 One-step validating parse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 978-6 Validating parse with predefined String ID assignments. . . . . . . . . . . . . . . . . . . . . . . . 978-7 Validating parse with predefined String ID assignments returning String IDs. . . . . . . . 988-8 Validating parse returning predefined String IDs and the OSR’s String ID table . . . . . 998-9 SAX parsing main program overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1008-10 Overview of document handler in SAX parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1018-11 DOM parsing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

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

Page 12: XML Processing on zOS

8-12 DOM tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1038-13 CICS as a Service Provider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1078-14 CICS Web Services Assistant. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1089-1 Creating a string ID handler exit routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1239-2 System services parameter area for the GXLESTRI StringIDHandler exit . . . . . . . . . 1249-3 System Services Vector passed to XML System Services . . . . . . . . . . . . . . . . . . . . . 1269-4 System services parameter area for the GXLE1IDI StringIDHandler exit. . . . . . . . . . 12910-1 XML processing eligible for zAAP or zIIP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13810-2 Overview XML processing from COBOL application . . . . . . . . . . . . . . . . . . . . . . . . 14010-3 Overview XML processing from PL/I Application . . . . . . . . . . . . . . . . . . . . . . . . . . . 14110-4 Overview XML processing from C or C++ Application . . . . . . . . . . . . . . . . . . . . . . . 14210-5 Overview XML processing from Assembler application . . . . . . . . . . . . . . . . . . . . . . 14210-6 Overview XML processing from Java application . . . . . . . . . . . . . . . . . . . . . . . . . . . 14311-1 Windows Notepad dialog box with encoding option highlighted . . . . . . . . . . . . . . . . 154

x XML Processing Options on z/OS

Page 13: XML Processing on zOS

Tables

1-1 Well-formed XML documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91-2 Standard XML schemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10A-1 List of supported encodings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164

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

Page 14: XML Processing on zOS

xii XML Processing Options on z/OS

Page 15: XML Processing on zOS

Examples

1-1 Simple XML document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21-2 External DTD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31-3 XML document with reference to external DTD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31-4 XML document with internal DTD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31-5 XML Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41-6 Corresponding Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41-7 XML document with duplicated element names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61-8 XML document using namespace prefixes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61-9 XML document using default namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71-10 XML Namespace declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71-11 XML Encoding Declaration for Unicode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81-12 XML Encoding Declarations for EBCDIC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81-13 XSLT stylesheet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125-1 COBOL XML GENERATE examples data description . . . . . . . . . . . . . . . . . . . . . . . . . 425-2 COBOL XML GENERATE basic element-style. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425-3 COBOL XML GENERATE with XML declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435-4 COBOL XML GENERATE Attribute-Style. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445-5 COBOL XML GENERATE with namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445-6 COBOL test of illegal characters. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455-7 COBOL hyphen in tag names to underscore routine . . . . . . . . . . . . . . . . . . . . . . . . . . 465-8 Output from a PL/I program using XMLCHAR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485-9 Output from the MEMCONVERT built-in function. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485-10 XML document before transformation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495-11 XSLT used to transform XML to HTML page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505-12 Xalan command line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505-13 HTML output from Xalan command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515-14 JCL to compile SMPLTRNS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525-15 JCL to link-edit the program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535-16 Same transformation using JCL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535-17 Changed source code for SimpleTransform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545-18 CICS Web Services Assistant, JCL Sample, DFHLS2WS . . . . . . . . . . . . . . . . . . . . . 585-19 Transform statement: Data to XML. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595-20 DB2 XMLELEMENT function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605-21 DB2 XMLSERIALIZE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 615-22 DB2 XMLSERIALIZE returning to a UTF-8 host variable . . . . . . . . . . . . . . . . . . . . . . 615-23 DB2 XMLAGG array of element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 615-24 DB2 XMLCONCAT array of element list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625-25 DB2 XMLELEMENT adding a parent element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625-26 DB2 XMLELEMENT return binary column in base64 . . . . . . . . . . . . . . . . . . . . . . . . . 635-27 DB2 XMLATTRIBUTES to generate attribute-style XML string . . . . . . . . . . . . . . . . . 635-28 DB2 Complete document with declaration and root element . . . . . . . . . . . . . . . . . . . 646-1 COBOL XMLPARSE with validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 826-2 COBOL/SQL examples of storing XML within DB2. . . . . . . . . . . . . . . . . . . . . . . . . . . . 838-1 Document handler interface description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1018-2 XML Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1038-3 DOMNode interface description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1048-4 CICS Web Services Assistant, JCL Sample, DFHLS2WS . . . . . . . . . . . . . . . . . . . . . 1088-5 Transform statement, parse XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

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

Page 16: XML Processing on zOS

8-6 Transform statement, parse XML, with ELEMNAME option . . . . . . . . . . . . . . . . . . . . 1098-7 Transform statement, unknown XML schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1098-8 DB2 parse without validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1108-9 DB2 commands to register an XML schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1118-10 DB2 insert with XML validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1119-1 Example JCL to run xsdosrg in batch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1149-2 Example of environment settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1159-3 Schema, list of xsd files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1159-4 Output from the OSRGEN tool in batch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1169-5 Directory listing to check the generated OSR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1169-6 Sequence of call to XML System Services to do a validated parse . . . . . . . . . . . . . . 1179-7 Program flow for navigating XML parsed data stream . . . . . . . . . . . . . . . . . . . . . . . . 1179-8 Error checking for navigating XML parsed data stream . . . . . . . . . . . . . . . . . . . . . . . 1199-9 Simple XML string to be parsed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1209-10 Buffer retuned by the parser with simple decoding. . . . . . . . . . . . . . . . . . . . . . . . . . 1219-11 Prolog for a METAL C program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1249-12 Conditional include for DSA handling in bare Metal C . . . . . . . . . . . . . . . . . . . . . . . 1259-13 How to fill the system services vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1269-14 Passing system services parameter to the x/OS XML parser. . . . . . . . . . . . . . . . . . 1269-15 XML System Services parameter for GXLE1IDI . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1279-16 Output buffer with string IDs from GXLESTRI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1279-17 StringID to string conversion with GXLESTRI. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1289-18 PL/I structure used as system services parameter for GXLE1IDI. . . . . . . . . . . . . . . 1299-19 Output from a parser using GXLE1IDI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1309-20 StringIDTable listing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1319-21 Call gxlini from a PL/I program going through the CVT. . . . . . . . . . . . . . . . . . . . . . . 1329-22 Defining a service using the options() in PL/I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1329-23 PL/I compile, bind and go with modification to include SYS1.CSSLIB . . . . . . . . . . . 1339-24 Turning on the XPLINK link from within a C/C++ program . . . . . . . . . . . . . . . . . . . . 1349-25 Command to compile and link a C/C++ program from the z/OS UNIX shell. . . . . . . 13411-1 iconv() syntax for converting to different code set . . . . . . . . . . . . . . . . . . . . . . . . . . 14911-2 XML document with EBCDIC encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15211-3 Result of GXL1QXD service for IBM01141 encoded XML document . . . . . . . . . . . . 15311-4 Result (XML flags) of GXL1QXD service for IBM01141 encoded XML document . . 15311-5 XML document with UTF-8 encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15511-6 Result of GXL1QXD service for UTF-8 encoded XML document . . . . . . . . . . . . . . . 15511-7 Result (XML flags) of GXL1QXD service for UTF-8 encoded XML document . . . . . 15511-8 XML document with UTF-16BE encoding. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15611-9 Result of GXL1QXD service for UTF-16BE encoded XML document . . . . . . . . . . . 15611-10 Result (XML flags) of GXL1QXD service for UTF-16BE encoded XML document . 15711-11 HTTP header with character encoding declaration. . . . . . . . . . . . . . . . . . . . . . . . . 158B-1 PL/I Generate XML example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165B-2 Simple PL/I program to parse without validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167B-3 C program to extract the STringIDTable. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176B-4 Enterprise COBOL program to call GXL1QXD program. . . . . . . . . . . . . . . . . . . . . . . 180B-5 Querying the sample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183B-6 C program to extract basic XML document information . . . . . . . . . . . . . . . . . . . . . . . 183B-7 COBOL program calling z/OS XML System Services on z/OS for parsing . . . . . . . . 187B-8 Enterprise COBOL program for parsing (without validation) and buffer management. 202B-9 C code to traverse an XML parsed record stream . . . . . . . . . . . . . . . . . . . . . . . . . . . 223B-10 Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237B-11 Output of the code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237

xiv XML Processing Options on z/OS

Page 17: XML Processing on zOS

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

Page 18: XML Processing on zOS

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®DB2®DRDA®eServer™i5/OS®IBM®IMS™Language Environment®

OS/390®OS/400®pureXML®Rational®Redbooks®Redpaper™Redbooks (logo) ®System z10™

System z9®System z®WebSphere®z/OS®z9®zSeries®

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

Page 19: XML Processing on zOS

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

Page 20: XML Processing on zOS

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 BostianMatthew CousensChris LarssonStephen DulinBill CareyIBM Systems & Technology Group, System z Software, Poughkeepsie NY

Thanks to the following reviewers:

David CargillSusan MalaikaJane ManGary MazoTom RossChristian Strauer

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

Bob HaimowitzInternational Technical Support Organization, Poughkeepsie Center

Susann ThomasIBM 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

Page 21: XML Processing on zOS

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:

[email protected]

� Mail your comments to:

IBM Corporation, International Technical Support OrganizationDept. HYTD Mail Station P0992455 South RoadPoughkeepsie, NY 12601-5400

Preface xix

Page 22: XML Processing on zOS

xx XML Processing Options on z/OS

Page 23: XML Processing on zOS

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.

1

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

Page 24: XML Processing on zOS

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

Page 25: XML Processing on zOS

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

Page 26: XML Processing on zOS

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

Page 27: XML Processing on zOS

<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

Page 28: XML Processing on zOS

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

Page 29: XML Processing on zOS

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

Page 30: XML Processing on zOS

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

Page 31: XML Processing on zOS

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

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.

Requirement Not Well-formed Example Well-formed Example

The document has exactly one root element

<element1>value1</element1><element2>value2</element2>

<element0><elem1>value1</elem1><elem2>value2</elem2>

</element0>

Each start tag is matched by one end tag

<elem1><elem2>value2

</elem1>

<elem1><elem2>value2</elem2>

</elem1>

All elements are properly nested <elem1><elem2>value2</elem1>

</elem2>

<elem1><elem2>value2</elem2>

</elem1>

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

Disallowed characters are not used in tags or values (Note 1)

<elem1> 123<456</elem1> <elem1> 123&lt;456</elem1>

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.

Chapter 1. XML essentials 9

Page 32: XML Processing on zOS

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

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.

Name description Industry

AMBER Alert Message Schema Justice

COLLADA COLLAborative Design Activity 3D Asset Exchange Schema

ITGamesGraphics

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

10 XML Processing Options on z/OS

Page 33: XML Processing on zOS

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

Page 34: XML Processing on zOS

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

Page 35: XML Processing on zOS

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

Chapter 1. XML essentials 13

Page 36: XML Processing on zOS

14 XML Processing Options on z/OS

Page 37: XML Processing on zOS

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.

2

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

Page 38: XML Processing on zOS

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

Page 39: XML Processing on zOS

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.

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.

XML ToolKit parser

XML Toolkit parser

XML

XML

XML

C++ SAXapplication

XML

C++ DOMapplication

HTML or text

z/OS XML System Services

z/OS XML System Services

XML ToolKit parser

z/OS XML System Services

XSLT

XML Toolkitfor z/OS

XSLTprocessor

Chapter 2. Overview of XML processing on System z 17

Page 40: XML Processing on zOS

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.

Figure 2-2 Parsing architecture for Enterprise COBOL

COBOL native XML

Parser

z/OS XML System

Services Parser

Enterprise COBOL Version 4

XML PARSE

z/OS XML System

Services Parser

CALL CALL

XML Toolkit for z/OS XSLT

Processor C++ Edition

CALL

XML Toolkit for z/OS

Parser C++ Edition

C glue codeC glue code

18 XML Processing Options on z/OS

Page 41: XML Processing on zOS

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.

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

PLISAXA XML

Parser

PL/I

z/OS XML System

Services

PLISAXB XML

Parser

PLISAXC XML

Parser

XML Toolkit XSLT

Processor C++ Edition

z/OS XML System Services

XML Toolkit Parser C++

Edition

C glue code

Chapter 2. Overview of XML processing on System z 19

Page 42: XML Processing on zOS

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.

Figure 2-4 CICS Transaction Server XML architecture

z/OS XML System

Services

Application SOAP message

CICS TS V3R1

CICSIntegrated

Parsing

CICS TS V4R1

Web Services Security

XMLToolkit

for z/OS Parser

20 XML Processing Options on z/OS

Page 43: XML Processing on zOS

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.

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.

XML Documents

IMSData0:oo0:oo

AUTH EDIT

BOOKPCB: BIB21

IMS DBD

PRICEPUBLISHTITLEYEAR

AFFLFIRSTLASTFIRSTLAST

XML Schema

author

last first

seq

xs:string xs:string

author

seq

xs:string xs:string xs:string

last first affiliation

book

@year

title

seq

pricepublisherchoicexs:date

xs:string xs:string xs:decimal

Chapter 2. Overview of XML processing on System z 21

Page 44: XML Processing on zOS

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

Page 45: XML Processing on zOS

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.

DB2 9pureXML

XML

XML

XMLresults

XMLresults

standard queryresults

Relational Tables

Native XMLcolumn

Query

Query

JoinQuery

Query

Chapter 2. Overview of XML processing on System z 23

Page 46: XML Processing on zOS

24 XML Processing Options on z/OS

Page 47: XML Processing on zOS

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

3

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

Page 48: XML Processing on zOS

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

Page 49: XML Processing on zOS

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

Page 50: XML Processing on zOS

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 servicesCICS 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.

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.

CICS TSV3R1

CICS WebServices

Service

requester

CICS

application program<XML SOAP

message>

COMMAREA

or CONTAINERSOAP/XMLconversion

WSDL

WSBindfile

COBOL, PLI,C, C++ commarea

definitionWeb Services

Assistant

28 XML Processing Options on z/OS

Page 51: XML Processing on zOS

CICS transform statementSince 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.

Figure 3-2 CICS transform statement

CICS

application program

EXEC CICSTransformDatatoXML

EXEC CICSTransformXMLtoData

SOAP/XMLconversion

WSBindfile

COBOL, PLI,C, C++ commarea

definitionWeb Services

Assistant

CICS TS

V4.1

Data in program structure

XML String

Data in program structure

XML String

Channel and Containers

XML Schema,WSDL

definition

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

Page 52: XML Processing on zOS

IMS and Web ServicesAs Figure 3-3 shows, IMS offers a number of interfaces for invoking IMS transactions.

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.

Figure 3-4 IMS and Web Services

y

IMSDB

ODBA

WAS zOS+ JDBC Driver

IMS Distribu ted

JDBC

JavaCom ponentEJB / Bean

WSDL RMI/

IIOP

WASIMS Distributed JDBC

IMSAppls.

OTMA

MQ-IMSBridge(XCF)

MQJMS to MQ

JavaComponentEJB / Bean

WSDL

MQ QueuesWASMQ to IMS Bridge

IMSAppls.

OTMA

IMSConnect

IMS Connector for

Java

JavaComponentEJB / Bean

WSDL TCP/IP

WASIMS Connect / IMS Connect Java Client

IMSAppls.

OTMA

IMSConnect

WSDL TCP/IP

IMS SOAP GatewayIMS SOAP Gateway –Technology Preview

WebSphere IICF JavaComponentEJB / Bean

WSDL

WebSphere IICF JDBC

Client

WASIMSDB

DRA/

ODBA

WebSphereIICFTCP/IP

IMSDB

IMSDB

IMSDB

IMSDB

IMSDB

IMSConnector

WebSphere ApplicationServer V4 or above

IMS 7.1 or above

XML

p1 InboundXML Converter

Driver

TraditionalCOBOLProgram

P1

p1 OutboundXML Converter

InQ

OutQ

30 XML Processing Options on z/OS

Page 53: XML Processing on zOS

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 servicesDB2 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.

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.

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.

DB2Requester

Web ServicesServer

StoredProcedure

SOAPHTTP

ODBCJDBC

DB2

Web ServicesServer

UserDefinedFunction

XYZ

SQL

HTTPSOAP

SELECT col_a, col_b,XYZ(col_c,col_d,”func”,

user_id)From my_table

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

Page 54: XML Processing on zOS

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.

Figure 3-8 Enterprise Service Bus

CICS TS

WebSphereApplication

Server

J2EE Java applications

IMS

WebSphereMQ

Messaging

DB2

SOAPHTTPIIOP

Connector

Connector

Connector

ODBCJDBC

Enterprise Service Bus

Service integration

bus

MQI Application

Human Tasks

JMSApplication BPEL

DataPower

WebSphere ESB

WebSphere Message Broker

WebSphere MQ

WBI Adapter CICS Web

ServiceMQTT

SCADA

32 XML Processing Options on z/OS

Page 55: XML Processing on zOS

Key for abbreviations in Figure 3-8 on page 32:

MQTT MQ Telemetry TransportWBI WebSphere Business IntegrationMQI Message Queue InterfaceJMS Java Messaging SystemBPEL Business Processing Execution LanguageSCADA 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.

Figure 3-9 DB2 as an XML warehouse

DB2XML XML column

OriginalXML

DB2

XML

RelationalData

shred

XML query

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

Page 56: XML Processing on zOS

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.

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.

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

X M L D o c u m e n ts

IM SD a ta0:oo0:oo

AUT H EDIT

BO O KPC B : B IB21

IM S D B D

PRICEPUBLISHTITLEYEAR

AFFLFIRSTLASTFIRSTLAST

X M L S c h e m a

author

last first

seq

xs:string xs:string

author

seq

xs:string xs:string xs:string

last first affiliation

book

@ year

title

seq

pricepublisherchoicexs:date

xs:string xs:string xs:decim al

CEETDLI Interface

JNI

Base

App

DB

Customer Code

IMS Java Class Library

Assembler Layer Interface to IMS

IMS DB MetadataBusiness Logic

Mapping to DL/I APIs

JDBC, JCAinterface Java to C

interface

JDBC/SQL XML-DB

IMS JavaApp

DLIDatabase

View

XML Shredder, XML Materializer

CodeIMS Dep. RegionTransaction and

Message Processing

34 XML Processing Options on z/OS

Page 57: XML Processing on zOS

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.

Figure 3-12 MQ messaging triggered listener applications

WebSphereMQ

Messaging

MQClient app

Putmessage

Triggerm

essage

TriggerMonitor

Listenerapp

Getmessage

Initiate Liste

ner App

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

Page 58: XML Processing on zOS

36 XML Processing Options on z/OS

Page 59: XML Processing on zOS

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.

4

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

Page 60: XML Processing on zOS

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.

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.

C IC S T S

C IC S t ra n s a c tio n

B u s in e s s a p p lic a t io n

S e rv ic e P ro v id e rS O A P M e s s a g e

C IC S W e b S e rv ic e s

C O M M A R E A o rC o n ta in e r

38 XML Processing Options on z/OS

Page 61: XML Processing on zOS

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.

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.

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.

Chapter 4. Overview of XML generation 39

Page 62: XML Processing on zOS

40 XML Processing Options on z/OS

Page 63: XML Processing on zOS

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.

5

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

Page 64: XML Processing on zOS

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-styleThe 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

Page 65: XML Processing on zOS

</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 declarationThe 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-listWITH DECLARATIONCOUNT 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

Page 66: XML Processing on zOS

<firstn>firstnName&lt;</firstn> </name><a2>

<country>DK</country> <redbooks>1</redbooks>

</a2></personnel>

</personnel-redbooks-list>

attribute-styleThe 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-listWIH ATTRIBUTESCOUNT 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 namespaceThe 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-listWIH ATTRIBUTESNAMESPACE ‘http://example’ NAMESPACE-PREFIX ‘prl’COUNT IN generated-length

END-XML

Produces:

44 XML Processing Options on z/OS

Page 67: XML Processing on zOS

<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 XMLWhen 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.lastn>.

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 ISSPACE ‘.’ ‘<‘ ‘(‘ ‘+’ ‘|’ ‘&’‘!’ ‘$’ ‘*’ ‘)’ ‘;’ ‘-’ ‘/’‘,’ ‘%’ ‘_’ ‘>’ ‘?’ ‘‘’ ‘:’ ‘#’ ‘@’ “‘” ‘=’ ‘”’‘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-xmlerror routine

END-IF

Chapter 5. How to generate XML 45

Page 68: XML Processing on zOS

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-ifif tagstate = 1

if xmldoc (pos:1) = ‘”’move 1 to quotestate

elsemove 0 to quotestate

end-ifend-ifif tagstate = 1 and quotestate = 0 and xmldoc (pos:1) = ‘-’

move ‘_’ to xmldoc (pos:1)else

if xmldoc (pos:1) = ‘>’move 0 to tagstateend-if

end-ifend-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

Page 69: XML Processing on zOS

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

Page 70: XML Processing on zOS

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

Page 71: XML Processing on zOS

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

Page 72: XML Processing on zOS

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

Page 73: XML Processing on zOS

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

Page 74: XML Processing on zOS

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

Page 75: XML Processing on zOS

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

Page 76: XML Processing on zOS

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

Page 77: XML Processing on zOS

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

Page 78: XML Processing on zOS

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

Page 79: XML Processing on zOS

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.

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.

CICS TS

User transaction

Data mapping

Pipeline

Handler

Handler

Handler

Service Provider

SOAP REQUEST

SOAP RESPONSE

Chapter 5. How to generate XML 57

Page 80: XML Processing on zOS

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.

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.SDFHSAMPREQMEM=DFH0XCP4RESPMEM=DFH0XCP4LANG=COBOLPGMNAME=DFH0XCMNURI=exampleApp/inquireSinglePGMINT=CHANNELWSBIND=/u/exampleapp/wsbind/inquireSingle.wsbindWSDL=/u/exampleapp/wsdl/inquireSingle.wsdl/*

Data mapping

Language

Structure

CICSWeb Services

Assistant

DFHLS2WS

HFS

WSBind

WSDL

HFS

WSBind

CICSWeb Services

Assistant

DFHWS2LS

PDS

HFS

WSDLSchema

PDS

Language

Structure

Bottom up

Top down

58 XML Processing Options on z/OS

Page 81: XML Processing on zOS

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 DATATOXMLXMLTRANSFORM('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.

ValidationThe 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

Page 82: XML Processing on zOS

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.

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.

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.

60 XML Processing Options on z/OS

Page 83: XML Processing on zOS

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

Page 84: XML Processing on zOS

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

Page 85: XML Processing on zOS

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

Page 86: XML Processing on zOS

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

Page 87: XML Processing on zOS

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.

6

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

Page 88: XML Processing on zOS

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.

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.

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.

66 XML Processing Options on z/OS

Page 89: XML Processing on zOS

6.1.1 Parsed XML data stream

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

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

GXLHXEC_TOK_START_ELEMrecord length

GXLHXEC_TOK_START_ELEMrecord length

GXLHXEC_TOK_START_ELEMrecord length

GXLHXEC_TOK_ATTR_NAMErecord length

GXLHXEC_TOK_ATTR_VALUErecord length

GXLHXEC_TOK_END_ELEMrecord length

GXLHXEC_TOK_END_ELEMrecord length

GXLHXEC_TOK_END_ELEMrecord length

GXLHXEC_TOK_BUFFER_INFOrecord length

datastream optionsparse status

buffer length usedoffset to error record

GXLHXEC_TOK_CHAR_DATArecord length

GXLHXEC_TOK_CHAR_DATArecord length

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

Page 90: XML Processing on zOS

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

Page 91: XML Processing on zOS

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.

XM

L st

ring

to p

arse

Buf

fer

Win

dow

Application

Out

put B

uffe

r

XML System Services

Filling

Acting

Reading

Ret

urn

and

Res

onco

de

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

Page 92: XML Processing on zOS

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 managementThe 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

Page 93: XML Processing on zOS

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

Page 94: XML Processing on zOS

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

72 XML Processing Options on z/OS

Page 95: XML Processing on zOS

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

Page 96: XML Processing on zOS

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

Page 97: XML Processing on zOS

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.

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: 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.

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

Page 98: XML Processing on zOS

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

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.

Application

Call Parse

XML System Services

Parse XML data

String ID Exit

Process parsed

data 21name7person3personnel-list

z/OS XML String ID Table

7End

Elem

Cdata John Doe

Elem ......

End

Elem21Elem7Elem3Elem

App String ID Table

PARSED DATA STREAM

21name7person3personnel-list

<personnel-list><person >

<name>John Doe</name>

...</person><person>

<name>Jane Doe</name>

...</person>

</Personnel-list>

XML System Services – String ID Exit Processing

Note: String IDs persist across multiple parses within a parser instance

76 XML Processing Options on z/OS

Page 99: XML Processing on zOS

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

Page 100: XML Processing on zOS

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

Page 101: XML Processing on zOS

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

Page 102: XML Processing on zOS

� 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

Page 103: XML Processing on zOS

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

Page 104: XML Processing on zOS

� 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-itemVALIDATING WITH osr-data-itemPROCESSING PROCEDURE xml-event-handler-nameON 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-itemVALIDATING WITH FILE schema-name1PROCESSING PROCEDURE xml-event-handler-nameON 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

Page 105: XML Processing on zOS

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-EXECEXEC SQL UPDATE tbl SET xml_col = :utf-8-xml-text END-EXECEXEC 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

Page 106: XML Processing on zOS

84 XML Processing Options on z/OS

Page 107: XML Processing on zOS

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.

7

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

Page 108: XML Processing on zOS

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.

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.

Native COBOLparser

z/OS XML System Services

COBOLXML PARSE

z/OS XML System Services

CALL

zAAP zAAP

86 XML Processing Options on z/OS

Page 109: XML Processing on zOS

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.

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

PLISAXAXML parser

PL/I

PLISAXBXML parser

PLISAXCXML parser

z/OS XML System

Services

z/OS XML System

Services

zAAP

zAAP

CALL

Chapter 7. Processing components, relationships, and options 87

Page 110: XML Processing on zOS

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

Page 111: XML Processing on zOS

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/Iapplications

Transforming XML input prior to parsingWhile 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.

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.

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

Transforming XML after generationAn 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.

COBOL, PL/Iparse

XMLXML Toolkit

for z/OSXSLT processor

TransformedXML

XML

XML Toolkitfor z/OS

XSLT processor

TransformedXML

XMLXML XMLXMLXML

COBOL, PL/IApplication

Position nextDocument

Invoke XSLT

Parse

Chapter 7. Processing components, relationships, and options 89

Page 112: XML Processing on zOS

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

COBOL, PL/Iparse

XMLXML Toolkit

for z/OSXSLT processor

TransformedXML

90 XML Processing Options on z/OS

Page 113: XML Processing on zOS

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 XMLSystem 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

Page 114: XML Processing on zOS

92 XML Processing Options on z/OS

Page 115: XML Processing on zOS

Chapter 8. How to parse XML

8

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

Page 116: XML Processing on zOS

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 parsingThe 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.

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

Non-validating parsing with String IDsString 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.

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.

ApplicationInvoking

ParseXML XML parseddata stream

z/OS XML

UserStringHandler

ApplicationInvoking

ParseXML

StringID Table

smallerXML parseddata stream

call

z/OS XML

lookup

94 XML Processing Options on z/OS

Page 117: XML Processing on zOS

Non-validating parsing with an initial predefined set of StringID valuesNormally, 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.

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

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 processThe 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.

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.

PredefinedStringID values

UserStringHandler

ApplicationInvoking

ParseXML

StringID Table

smallerXML parseddata stream

call

z/OS XML

lookup

Note 1

Chapter 8. How to parse XML 95

Page 118: XML Processing on zOS

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

Figure 8-4 Two-step validating parse

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 processThe 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.

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

Read and Load OSR

Parse with validation

Process data stream

Load Schema

Generate OSR

Write OSR

xsdschema

StringID table

OSRStringID

table

XMLXML parsedData stream

z/OS XML

z/OS XML

z/OS XML

z/OS XML

Step 1Step 2

Note 2

96 XML Processing Options on z/OS

Page 119: XML Processing on zOS

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 assignmentsBy 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.

Figure 8-6 Validating parse with predefined String ID assignments

XSD

StringID table

OSRStringID

table

Load Schema

Generate OSR

Write OSR

Load (point to)OSR

Parse with validation

Process data stream

XML

XML parsedData stream

z/OS XML

z/OS XML

z/OS XML

z/OS XML

OSRGENERATE

XSD

UserStringHandler

Complete OSRStringID table

OSRStringID

table

Load OSR

Parse withValidation

Process stream

XML

PredefinedStringID

assignments

call

XML parseddata stream

z/OS XML

z/OS XML

Chapter 8. How to parse XML 97

Page 120: XML Processing on zOS

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 StringIDsAll 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.

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 tableOne 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.

UserStringHandler

OSRGENERATE

XSD

UserStringHandler

Complete OSRStringID table

OSRStringID

table

Load OSR

Parse withValidation

Process stream

XML

StringID Table

SmallerXML parsedData stream

PredefinedStringID

assignments

call

calllo

okup

z/OS XML

z/OS XML

98 XML Processing Options on z/OS

Page 121: XML Processing on zOS

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.

UserStringHandler

OSRGENERATE

XSD

UserStringHandler

Complete OSRStringID table

OSRStringID

table

Load OSR

Extract StringTable

Parse wihValidation

Process data stream

XML

StringID Table

XML parsedData stream

PredefinedStringID

assignments

call

call

OSR’sStringID Table

look

up

z/OS XML

z/OS XML

z/OS XML

Chapter 8. How to parse XML 99

Page 122: XML Processing on zOS

� 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.

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)

Initialize XML4C system

Create an instance of the parser

Declare and register Handlers

Set parser features

Start Parsing

Clean up

XMLplatformUtils::Initialize();

SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();

SAX2CountHandlers handler;parser -> setContentHandler(&handler);parser -> setErrorHandler(&handler);

parser -> setFeature(XMLUni::fgSAX2CoreNoameSpaces,doNamespaces);

parser -> setFeature(XMLUni::fgSAX2CoreNameSpacePrefixes,

namespacesPrefixes);

parser -> parse(xmlFile);

Delete parser;

Terminate XML4C system XMLplatformUtils::Terminate();

Parsing function Coding sample

100 XML Processing Options on z/OS

Page 123: XML Processing on zOS

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.

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

Start Parsing

The XML4C parser invokes the document handler routinefor each event in the XML string

The feature invoked signals the document handler which event is occurred.

If the parser finds an error in the XMLDocument, information is communicatedto the application using the error handler

Parsing function Document handler method called

parser -> parse(xmlFile);

StartDocumentStartElement

StartElementCharacters

EndElementStartElement

Characters EndElementStartElement

Characters EndElement

EndElementEndDocument

Chapter 8. How to parse XML 101

Page 124: XML Processing on zOS

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.

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.

Initialize XML4C system

Create an instance of the parser

Declare and create Handlers

Set parser features and register handlers with parser

Parse the document and build the DOM tree

Get DOM representation andparse it on to Writer

XMLplatformUtils::Initialize();

XercesDOMParser * parser = new XercesDOMParser();

DOMtreeErrorReporter * errReporter = new DomTreeErrorReporter();

DOMWriter * theSerializer = ((DOMImplementationLS*)impl)->createDOMWriter();

parser -> setValidationScheme(gValScheme);parser -> setDoSchema(gDoSchema); parser -> setErrrorHandler(errReporter);

parser -> parse(gxmlFile);

DOMNode * doc = parser->getDocument();theSerializer->writeNode(myformTarget, *doc);

Clean up andTerminate XML4C system

Delete parser; Delete errReporter;XMLplatformUtils::Terminate();

Parsing function Coding sample

102 XML Processing Options on z/OS

Page 125: XML Processing on zOS

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.

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.

Root element<library>

Element<book>

Element<author>

Element<year>

Element<title>

Element<ISBN>

CharacterDataAlice’s Adventure

in Wonderland

CharacterDataLewis Carrol

CharacterData1865

CharacterData0000123456

Element<book>

Attribute“country”

CharacterDataUK

Attribute“language”

CharacterDataEnglish

Element<author>

Element<year>

Element<title>

Element<ISBN>

CharacterDataXML processing

on z/OS

CharacterDataMike Ebbers CharacterData

2009CharacterData0000123458

Attribute“country”

CharacterDataUS

Element<author>

CharacterDataHans-Dieter Mertiens

Attribute“country”

CharacterDataDE

Siblings

Child

Parent

Chapter 8. How to parse XML 103

Page 126: XML Processing on zOS

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

Page 127: XML Processing on zOS

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

Page 128: XML Processing on zOS

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

Page 129: XML Processing on zOS

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).

CICS TSUser transaction

CWXN

Pipeline

Handler

Handler

Handler

CSOLIP-Socket Listener

Service Requester SOAP Request

SOAP Response

Handler

Handler

Handler

Pipeline

BusinessLogic

Chapter 8. How to parse XML 107

Page 130: XML Processing on zOS

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.SDFHSAMPREQMEM=DFH0XCP4RESPMEM=DFH0XCP4LANG=COBOLPGMNAME=DFH0XCMNTRANSACTION=XML1MAPPING-LEVEL=2.0URI=exampleApp/inquireSinglePGMINT=CHANNELWSBIND=/u/exampleapp/wsbind/inquireSingle.wsbindWSDL=/u/exampleapp/wsdl/inquireSingle.wsdl/*

CICS Web Services supports the following security protocols:

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

Data mapping

Language

Structure

CICSWeb Services

Assistant

DFHLS2WS

HFS

WSBind

WSDL

HFS

WSBind

CICSWeb Services

Assistant

DFHWS2LS

PDS

HFS

WSDLSchema

PDS

Language

Structure

Bottom up

Top down

108 XML Processing Options on z/OS

Page 131: XML Processing on zOS

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 XMLTODATAXMLTRANSFORM('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 XMLTODATAXMLTRANSFORM('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 XMLTODATACHANNEL('MyChannelName')XMLCONTAINER('SourceContainerName')ELEMNAME(elementName) ELEMNAMELEN(elementNameLength)

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

Chapter 8. How to parse XML 109

Page 132: XML Processing on zOS

ValidationThe 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-hostSTRIP 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

Page 133: XML Processing on zOS

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

Page 134: XML Processing on zOS

112 XML Processing Options on z/OS

Page 135: XML Processing on zOS

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.

9

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

Page 136: XML Processing on zOS

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.

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

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.

114 XML Processing Options on z/OS

Page 137: XML Processing on zOS

//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=YESLIBPATH=/usr/lib:/usr/lpp/java/J5.0/bin:/usr/lpp/java/J5.0/bin/j9vm:/usr/lib/java_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

Page 138: XML Processing on zOS

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

Page 139: XML Processing on zOS

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

Page 140: XML Processing on zOS

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

Page 141: XML Processing on zOS

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

Page 142: XML Processing on zOS

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

Page 143: XML Processing on zOS

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

Page 144: XML Processing on zOS

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 cloneThe 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.

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.

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

122 XML Processing Options on z/OS

Page 145: XML Processing on zOS

Figure 9-1 Creating a string ID handler exit routine

We then copied the Assembler version of it (stridx.s) into a partitioned data set for the following steps.

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.

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.

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.

Process to build C and its Metal C companion for

C sourceStrIDx.c

xlc –c StrIDx.c xlc -WC,nosearch -S -qmetal –I /usr/include/metal/ StrIDx.c (*)

Make a dll xlc -c StrIDx.s

* Note: for display purposes only the xlc command is split across lines

Chapter 9. Hints, tips, and samples 123

Page 146: XML Processing on zOS

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.

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 */

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

124 XML Processing Options on z/OS

Page 147: XML Processing on zOS

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

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 VectorAnother 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.

Note: The system services parameter is used as work area for the StringIDHandler exit.

Chapter 9. Hints, tips, and samples 125

Page 148: XML Processing on zOS

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.

Counter

Storage Allocation or NULL

Storage Deallocation or NULL

StringIDHandler

XML System Services Vector Layout

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)

126 XML Processing Options on z/OS

Page 149: XML Processing on zOS

How to populate the system services parameter areaDepending 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; .

� 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 00000006GXL_RT_START_ELEM 7 00000007GXL_RT_START_ELEM 8 00000008GXL_RT_START_ELEM 9 00000009GXL_RT_CHAR_DATA 4 Hans GXL_RT_END_ELEM GXL_RT_START_ELEM 10 0000000AGXL_RT_CHAR_DATA 8 MertiensGXL_RT_END_ELEM GXL_RT_END_ELEM GXL_RT_START_ELEM 11 0000000B

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.

Chapter 9. Hints, tips, and samples 127

Page 150: XML Processing on zOS

GXL_RT_START_ELEM 12 0000000CGXL_RT_CHAR_DATA 3 HDM GXL_RT_END_ELEM GXL_RT_START_ELEM 13 0000000DGXL_RT_CHAR_DATA 4 SYS1 GXL_RT_END_ELEM GXL_RT_END_ELEM GXL_RT_START_ELEM 14 0000000EGXL_RT_START_ELEM 15 1 0000000FGXL_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 GXL1IDIIn 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

Page 151: XML Processing on zOS

Figure 9-4 shows the layout needed by the exit.

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 */

GXLE1IDI System Services Parameter Area

Header information

ID list area

Dynamic Area

Free Area

Application needs to provide important header informationThe grey shaded area contains data relevant to the exitThe green shaded area holds the string ID table

Chapter 9. Hints, tips, and samples 129

Page 152: XML Processing on zOS

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

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.

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.

130 XML Processing Options on z/OS

Page 153: XML Processing on zOS

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) 24Number 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 6XSTR_TBLENTRY_STRID 00000001 _STRLEN 00000005 _OFFSET 00000000 string xmlns

stepp at 19F7E064 6XSTR_TBLENTRY_STRID 00000002 _STRLEN 00000003 _OFFSET 00000006 string xml

stepp at 19F7E07C 6XSTR_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

Page 154: XML Processing on zOS

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

Page 155: XML Processing on zOS

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

Page 156: XML Processing on zOS

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

Page 157: XML Processing on zOS

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.

10

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

Page 158: XML Processing on zOS

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

Page 159: XML Processing on zOS

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

Page 160: XML Processing on zOS

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.

Figure 10-1 XML processing eligible for zAAP or zIIP

TCB

SRB

TCB

SRB

SRB

TCB

MVS Execution

Mode

zAAP

zIIP

zAAP

zIIP

zIIP

zAAP

Any z/OS, system z processor with zAAP support

100% of Java-based XML parsiingeligible for zAAP

Applications using Java-based XML parser in IBM SDKAny software performing XML parsing/processing I Java

z/OS 1.9DB2 V9 New Function Mode

100% of z/OS XML System Services parsing eligible for zAAP

Any software using z/OS XML System Services validating parsing

z/OS 1.9XML Toolkit for z/OS v1.10Enterprise COBOL V4.2DB2 V9 New Function Mode

100% of z/OS XML System Services parsing eligible for zAAP

Any software using z/OS XML System Services validating parsing

z/OS 1.7DB2 V9 New Function Mode

100% of z/OS XML Systems Services parsing eligible for zIIP

Any software using z/OS XML System Services non validating parsing

z/OS 1.8DB2 V.9 New Function Mode

Same % as the zIIP eligible work (DRDA)

DB2 v.9 inserting/saving XML data using DRDA via TCP/IP

z/OS 1.7XML Toolkit for z/OS v1.9Enterprise COBOL V4.1PL/1 V3.8DB2 V9 New Function Mode CICS TS 4.1

100% of z/OS XML System Services parsing eligible for zAAP

- Any software using z/OS XML System Services non validating parsing- XML Toolkit for z/OS parsing workloads using z/OS classes- Enterprise COBOL, using XMLPARSE option- Enterprise PL/1- CICS Web Services/SOAP

RequirementsRedirectWorkload examples

138 XML Processing Options on z/OS

Page 161: XML Processing on zOS

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

Page 162: XML Processing on zOS

10.5.1 COBOL

From a COBOL application you have several options for handling XML. Figure 10-2 shows the main possibilities.

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.

COBOL Application

COBOL Built-in parser

XML Toolkit

XML System services

General Purpose

CPU

General Purpose

CPU

zAAPCPU

zAAPCPU

zAAPCPU

zAAPCPU

General Purpose

CPU

CICS WEB Services

XML System services

140 XML Processing Options on z/OS

Page 163: XML Processing on zOS

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.

PL/I Application

PL/I Built-in parser

XML Toolkit

XML System services

General Purpose

CPU

General Purpose

CPU

zAAPCPU

zAAPCPU

zAAPCPU

zAAPCPU

General Purpose

CPU

CICS WEB Services

XML System services

Chapter 10. Performance recommendations and cost perspectives 141

Page 164: XML Processing on zOS

See Figure 10-4.

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.

Figure 10-5 Overview XML processing from Assembler application

CICS TS 4.1 is required to offload CICS Web Services work to zAAP.

C/C++ Application

CICS Web Services

XML Toolkit

XML System services

General Purpose

CPU

General Purpose

CPU

zAAPCPU

zAAP orzIIPCPU

zAAPCPU

Assembler Application

CICS Web Services

XML Toolkit

XML System services

General Purpose

CPU

General Purpose

CPU

zAAPCPU

zAAP orzIIPCPU

zAAPCPU

142 XML Processing Options on z/OS

Page 165: XML Processing on zOS

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.

Figure 10-6 Overview XML processing from Java application

Java Application

CICS Web Services

Native XML Java classes

XML System Services

General Purpose

CPU

General Purpose

CPU

zAAPCPU

zAAPCPU

zAAPCPU

zAAPCPU

Chapter 10. Performance recommendations and cost perspectives 143

Page 166: XML Processing on zOS

144 XML Processing Options on z/OS

Page 167: XML Processing on zOS

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.

11

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

Page 168: XML Processing on zOS

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.

CharacterA character is an “atomic” symbol used in a language.

Character setA 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 setA 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 encodingA 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

ASCIIASCII 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

Page 169: XML Processing on zOS

EBCDICEBCDIC (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®.

UnicodeUnicode 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.

WhitespaceThe 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)

BOMBOM (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.

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.

Chapter 11. XML and character encoding issues 147

Page 170: XML Processing on zOS

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-8UTF-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-16BEUTF-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

Page 171: XML Processing on zOS

� 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

� 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 encodingBefore 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.

Important: After doing this conversion, be sure to update the encoding= statement in the new document to reflect the new encoding.

Chapter 11. XML and character encoding issues 149

Page 172: XML Processing on zOS

Supported code pagesThe 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 overridesWhen 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 XMLThe 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

Page 173: XML Processing on zOS

BOMA 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 encodingBroadly 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 pagesOther 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 overridesIf 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 XMLThese routines do not support generation of XML. To generate XML, the built-in function XMLCHAR must be used.

BOMThe 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

Page 174: XML Processing on zOS

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

Page 175: XML Processing on zOS

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 : 000000226QXD Version : 1XML Autodet Value : 8XML Autodet CCSID : 37XML Version : 1XML Release : 0XML Spec CCSID : 1141XML Reserved : 0XML Decl Length : 58

Example 11-4 Result (XML flags) of GXL1QXD service for IBM01141 encoded XML document

XML Flags 1 : Ø EDD4C988A4F44444447484743063172010000000A000----------------------XML Flags 2 : Ö EDD4C988A4F444444474E4743063172020000000A000

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.

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.

Chapter 11. XML and character encoding issues 153

Page 176: XML Processing on zOS

� 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

Page 177: XML Processing on zOS

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 : 000000254QXD Version : 1XML Autodet Value : 7XML Autodet CCSID : 1208XML Version : 1XML Release : 0XML Spec CCSID : 1208XML Reserved : 0XML Decl Length : 58

Example 11-7 Result (XML flags) of GXL1QXD service for UTF-8 encoded XML document

XML Flags 1 : äEDD4C988A4F444444474C743063172010000000A00---------------------XML Flags 2 : ÖEDD4C988A4F444444474E743063172020000000A00

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

Page 178: XML Processing on zOS

� 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 : 000000504QXD Version : 1XML Autodet Value : 5XML Autodet CCSID : 1200XML Version : 1XML Release : 0XML Spec CCSID : 1200XML Reserved : 0XML 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

Page 179: XML Processing on zOS

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 : äEDD4C988A4F444444474C743063172010000000A00---------------------XML Flags 2 : ÖEDD4C988A4F444444474E743063172020000000A00

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

Page 180: XML Processing on zOS

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 OKDate: Wed, 13 May 2009 10:46:04 GMTServer: Apache/1.3.28 (Unix) PHP/4.2.3Content-Location: CSS2-REC.en.htmlVary: negotiate,accept-language,accept-charsetTCN: choiceP3P: policyref=http://www.w3.org/2001/05/P3P/p3p.xmlCache-Control: max-age=21600Expires: Wed, 13 May 2009 16:46:04 GMTLast-Modified: Tue, 12 May 2008 22:18:49 GMTETag: "3558cac9;36f99e2b"Accept-Ranges: bytesContent-Length: 10734Connection: closeContent-Type: text/html; charset=iso-8859-1Content-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

Page 181: XML Processing on zOS

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

Page 182: XML Processing on zOS

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

Page 183: XML Processing on zOS

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/lpaths/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

Page 184: XML Processing on zOS

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

Page 185: XML Processing on zOS

Appendix A. Supported character encoding

This appendix describes the list of code pages supported by z/OS XML System Services on z/OS.

A

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

Page 186: XML Processing on zOS

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

Page 187: XML Processing on zOS

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' ;

B

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

Page 188: XML Processing on zOS

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

Page 189: XML Processing on zOS

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

Page 190: XML Processing on zOS

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

Page 191: XML Processing on zOS

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

Page 192: XML Processing on zOS

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

Page 193: XML Processing on zOS

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

Page 194: XML Processing on zOS

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

Page 195: XML Processing on zOS

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

Page 196: XML Processing on zOS

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

Page 197: XML Processing on zOS

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

Page 198: XML Processing on zOS

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

Page 199: XML Processing on zOS

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

Page 200: XML Processing on zOS

/* 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

Page 201: XML Processing on zOS

/* 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

Page 202: XML Processing on zOS

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

Page 203: XML Processing on zOS

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

Page 204: XML Processing on zOS

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

Page 205: XML Processing on zOS

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 runningc89 -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

Page 206: XML Processing on zOS

#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

Page 207: XML Processing on zOS

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

Page 208: XML Processing on zOS

"\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

Page 209: XML Processing on zOS

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 . *

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.

Appendix B. Program source files 187

Page 210: XML Processing on zOS

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

Page 211: XML Processing on zOS

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

Page 212: XML Processing on zOS

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

Page 213: XML Processing on zOS

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

Page 214: XML Processing on zOS

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

Page 215: XML Processing on zOS

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

Page 216: XML Processing on zOS

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

Page 217: XML Processing on zOS

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

Page 218: XML Processing on zOS

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

Page 219: XML Processing on zOS

. 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

Page 220: XML Processing on zOS

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

Page 221: XML Processing on zOS

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

Page 222: XML Processing on zOS

* 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

Page 223: XML Processing on zOS

(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

Page 224: XML Processing on zOS

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

Page 225: XML Processing on zOS

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

Page 226: XML Processing on zOS

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

Page 227: XML Processing on zOS

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

Page 228: XML Processing on zOS

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

Page 229: XML Processing on zOS

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

Page 230: XML Processing on zOS

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

Page 231: XML Processing on zOS

* 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

Page 232: XML Processing on zOS

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

Page 233: XML Processing on zOS

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

Page 234: XML Processing on zOS

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

Page 235: XML Processing on zOS

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

Page 236: XML Processing on zOS

. 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

Page 237: XML Processing on zOS

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

Page 238: XML Processing on zOS

* 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

Page 239: XML Processing on zOS

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

Page 240: XML Processing on zOS

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

Page 241: XML Processing on zOS

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

Page 242: XML Processing on zOS

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

Page 243: XML Processing on zOS

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

Page 244: XML Processing on zOS

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

Page 245: XML Processing on zOS

B.8 C program to traverse a z/OS XML parsed record streamand 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 prototypesint 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

Page 246: XML Processing on zOS

#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

Page 247: XML Processing on zOS

#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

Page 248: XML Processing on zOS

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

Page 249: XML Processing on zOS

// 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

Page 250: XML Processing on zOS

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

Page 251: XML Processing on zOS

{ // 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

Page 252: XML Processing on zOS

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

Page 253: XML Processing on zOS

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

Page 254: XML Processing on zOS

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

Page 255: XML Processing on zOS

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

Page 256: XML Processing on zOS

{ // 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

Page 257: XML Processing on zOS

{ // 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

Page 258: XML Processing on zOS

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

Page 259: XML Processing on zOS

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>[email protected]</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

Page 260: XML Processing on zOS

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 [email protected]+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

Page 261: XML Processing on zOS

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 Description7810code.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

C

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

Page 262: XML Processing on zOS

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

Page 263: XML Processing on zOS

ronyms

ASCII American Standard Code for Information Interchange

BOM Byte Order Mark

CICS Customer Information Control System

CSS Cascading Style Sheet

DOM Document Object Model

DTD Data Type Definition

EBCDIC Extended Binary Coded Decimal Interchange Code

ESB Enterprice Service Bus

ESDS VSAM Entry Sequenced Data Set

GDG Generation Data Group

HFS z/OS UNIX Hierarchial File System

HTML Hyper Text Markup Language

IBM International Business Machines Corporation

ITSO International Technical Support Organization

KSDS VSAM Key Sequenced Data Set

OSR Optimized Schema Representation

PDS Partitioned Data Set

PDSE Partitoned Data Set Extended

RRDS VSAM Relative Record Data Set

SAX Simple API for XML

SGML Standard Generalized Markup Language

SOAP Simple Object Access Protocol

UTF Unicode Transformation Format

VSAM Virtual Storage Access Method

WAS WebSphere Application Server

XLL XML Linking Language

XML Extensible Markup Language

XPATH XML Path Language

XPLINK eXtra Performance Linkage

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

Abbreviations and ac

© Copyright IBM Corp. 2009. All rights reserved.

zAAP System z Application Assist Processor

zIIP System z Integrated Information Processor

ASCII American Standard Code for Information Interchange

BOM Byte Order Mark

CICS Customer Information Control System

CSS Cascading Style Sheet

DOM Document Object Model

DTD Data Type Definition

EBCDIC Extended Binary Coded Decimal Interchange Code

ESB Enterprice Service Bus

ESDS VSAM Entry Sequenced Data Set

GDG Generation Data Group

HFS z/OS UNIX Hierarchial File System

HTML Hyper Text Markup Language

IBM International Business Machines Corporation

ITSO International Technical Support Organization

KSDS VSAM Key Sequenced Data Set

OSR Optimized Schema Representation

PDS Partitioned Data Set

PDSE Partitoned Data Set Extended

RRDS VSAM Relative Record Data Set

SAX Simple API for XML

SGML Standard Generalized Markup Language

SOAP Simple Object Access Protocol

UTF Unicode Transformation Format

VSAM Virtual Storage Access Method

WAS WebSphere Application Server

XLL XML Linking Language

241

Page 264: XML Processing on zOS

242 XML Processing Options on z/OS

Page 265: XML Processing on zOS

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
Page 266: XML Processing on zOS

244 XML Processing Options on z/OS

Page 267: XML Processing on zOS

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

Page 268: XML Processing on zOS

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

Page 269: XML Processing on zOS

Index

Symbols

__IBM_METAL__ 125_BPX_AUTOCVT 161_BPXK_CCSIDS 161.profile 115/usr/include/metal 123

Aacceptable codepages 139American Standard Code for Information Interchange (ASCII) 146application program 27, 70, 79, 86, 107, 160application programming interface (API) 10, 23, 67, 86, 100application startup 26assembler 27, 35, 67, 88, 142assembler interface 137attribute-style 44author country 103automatic conversion 139, 154

Bbare metal C

code variant 88environment 123

BASE64 60basic XML

definition 8document information 183

BI (business intelligence) 138big endian

format 156binary zero 9body bgcolor 12built-in function

XMLCHAR 151Business Processing Execution Language (BPEL) 33byte-order-mark (BOM) 80, 147, 185

CC 27, 88–89, 141C/C++ language binding 66, 133C++ 27, 88–89, 141carriage return (CR) 8, 147CCSID 146, 157, 161, 167char b 176character 146

ASCII 146character encoding 146character set 146coded character set 146

© Copyright IBM Corp. 2009. All rights reserved.

coded character set ID 146EBCDIC 147iconv() 149Unicode 147

child nodeoldChild 104

chtag 162CICS 20, 26, 28, 31, 35, 38CICS transaction 35, 107

werver 20, 161CICS TS 20, 28, 38

3.2 1404.1 20, 29, 38–39, 109, 141

CICS Web Service 20, 38, 57, 106–107, 140CICS Web Services Assistant 58, 107COBOL 16–17, 21, 27, 86, 139–140, 149–150

generating 42COBOL application 86, 106, 140COBOL XML

PARSE 82CODEPAGE 149, 165COMMAREA 161Comp-5 Value 0 189complete list 123, 139, 148CSSLIB 132CUNLCNV 48CVT 132

Ddata stream 16, 67, 94, 117, 119, 149DB2 22, 26–28, 33, 35, 39DB2 9 22, 39, 82, 110

pureXML 22DB2 database 160DB2 XML functions

XML2CLOB 60XMLAGG 60–61XMLATTRIBUTE 60XMLATTRIBUTES 63XMLCOMMENT 60XMLCONCAT 60, 62XMLDOCUMENT 60XMLELEMENT 60, 62–63XMLFOREST 60XMLNAMESPACE 60XMLPI 60XMLQUERY 60XMLSERIALIZE 60–61XMLTEXT 60

DD DISP 115DD name

OUTDATA 186TSTXML 186

Document Object Model (DOM) 10–11, 27

247

Page 270: XML Processing on zOS

document typedefinition 2, 188

document validation 16, 86, 95DOM parsing 102DOM tree 11, 80, 102–103DSA 125DTD 2Dynamic Stack Area (DSA) 123

EEBCDIC code

page 148element name 4, 6, 70, 109, 128ELEMENT TELEFONO2 3element-style 42enclave 88encoding 7, 139Enterprise 81enterprise COBOL 17–18, 38, 81, 86, 106, 117, 149, 180

Parsing architecture 18program 183V3R1 18V4 18V4R1 17XML System Service parser 91

enterprise PL/I 19, 38, 81, 87, 138, 151Enterprise Service Bus (ESB) 22, 26, 32ENVAR 115epilog 125ESB 31ESDS 26EXEC SQL

Call 31UPDATE tbl SET xml_col 83

existing language structureWSDL document 107

Extended Binary Coded Decimal Interchange Code (EBCDIC) 147external DTD 2

FFD TstXML 188fetch 126file transfer protocol (FTP) 26, 152FILETAG 161

GGDG 26, 28generating

COBOL 38, 42, 45PL/I 19, 38, 48

Generating COBOL 81GET CONTAINER 161GROUP-USAGE National 149gxl_lvpairs 117, 169gxl_valchs 169gxl_vallen 117, 169gxl1ini entry 132, 167

gxl1prs entry 168GXL1QXD service 153, 180GXLESTRI 122–123

HHans-Dieter Mertiens 103header flag 224heterogeneous system 148, 158Hierarchical File System (HFS) 26, 100, 147HTML page 12HTTP 158HTTP header 158

encoding declarations 158meta charset declaration 158

Hyphes in element names 46

IIANA 161IBMZCBG 133IMS 21, 26, 28, 31, 34IMS data 34IMS database 21, 34input buffer 68–69, 119, 167Input-Buffer-Length XML-Doc-Len 199int argc 176internal DTD 2, 79

ENTITY attribute 79invalid XML 136

document 136structure 2

ISO-10646 45

JJ2EE 31Java 22, 143Java Messaging System (JMS) 33JMS See messagingJOBPARM SYSAFF 114

KKSDS 26

Llanguage binding 68, 131, 133Language Environment 66, 88, 122

binding 142run-time dependancy 122

language structure 106left-over byte 71line feed (LF) 8, 147Linux 23

MMEMCONVERT 48, 165message queue (MQ) 29message queue interface (MQI) 33

248 XML Processing Options on z/OS

Page 271: XML Processing on zOS

message transmission optimization mechanism (MTOM) 20messaging 26, 31, 35Metal C 122

conversion 123environment 123version 122

MOVE 1 195move function 200Move GXL1PRS-Reason-Code 193Move GXL1PRS-Return-Code 193move space 192move zero 192MQ message 18, 90MQ message broker 32MQ Messaging see messagingMQ queue

manager 159reading program 35

MQ See messagingMQ server 158MTOM 22multiple buffer 66mutable field 119, 171MVS 100

Nname space

prefix 81namespace declaration 5, 67

xmlns keyword 6namespace URI 105namespaces 6native Java 22newline 148, 223non-validating parse 94, 99non-validating parsing

basic approaches 94non-XPLINK

environment 136version 100, 136

NS prefix 231NS URI 231

OOCOPY 162OGET 162OGETX 162optimized schema representation (OSR) 75, 82, 95, 98, 114, 176–177OPUT 162OPUTX 162original XML

document 33–34form 33string 33

OSR generation 96output buffer 68, 70, 86, 119, 168

minimum size 70

Pparsed data

stream 67, 69, 94, 119parser instance memory area (PIMA) 66, 161parsing 95

COBOL 18, 81, 89–91, 149COBOL with validation 82PL/I 16, 19, 81, 87, 89–91, 140

parsing and validation with XML Toolkit 78Parsing COBOL 38parsing PL/I 19, 38parsing with XML Toolkit for z/OS 76partitioned data set extended (PDSE) 114PDS 26PDSE 26PIC N 149PIMA length 132, 167PL/I 27, 139, 151

application 19, 87, 106, 140example 117generating 48program 66, 117, 119

Call gxlini 132complete listing 119

pointer byaddr 132, 167pointer byvalue 132, 167POSIX(ON) 115pragma runopts 134, 176predefined String IDs 99process server 22, 26, 32processing instruction (PI) 5, 80, 101programming language 2, 15, 27, 99, 154PTFs UA40707 137pureXML 33PUT CONTAINER 161

QQXD Version 153, 182

RRational Developer for System z 21Read TstXML 182reason code 68–70, 119, 132, 157, 167, 180Redbooks Web site 246

Contact us xixreturn code 68, 70, 119, 132, 157, 167REXX 67routines PLISAXA 81, 151RRDS 26rsn 117, 175rsv 226

Ssample useLang 152SAMPLIB 122SAX 10, 27Schema 4schema URLs 5

Index 249

Page 272: XML Processing on zOS

Select OutData 188Select TstXML 180service request block (SRB) 66, 88Simple API for XML (SAX) 10SO-10646 46SOAP 22, 31sparse parsing 95SQL guide 83, 111SQL Type

host variable 83SQL type 83SRB 88

mode 22, 138Standard Generalized Markup Language (SGML) 2Standard OS Linkage 132static init 167String IDs

Non-validating parsing 94string IDs 76, 94, 98, 127String Message-Level 210StringID 75, 94–95, 97–98, 122StringID Table 76, 94, 130StringID value 95StringIDHandler 75StringIDTable 122, 176Supervisory Control And Data Acquisition (SCADA) 33SYS1.CSSL IB 132, 180SYS1.SAMPLIB 128SYSLIB 132SYSOUT 26system services parameter area 75system services vector 125System z 15, 25, 88–89, 145, 147–148

common exit points 26DB2 V8 35extensible means 88Linux 23preferred encoding 148Rational Developer 21WebSphere MQ Messaging 35XML documents 160XML processing 16XML-enabled products 16

Ttag name 69task control block (TCB) 88toolkit 76, 88, 136, 147toolkit parser 16transform statement (TS) 20, 28, 109transformation 16–17, 80, 88–89

XML to record 88XML to XML 88

transforming 89

UUnicode service 149Unicode Transformation Format (UTF) 146UNIX environment 100

UNIX HFS 26UNIX z/FS 26USAGE National 149user-defined functions (UDF) 31UTF scheme 147UTF-16BE 148UTF-8 148

Vvalid XML 110

document 152stream 17string 21

validate 136validating parsing 97validation 9, 110, 136validation COBOL 82value space 181virtual DOMNode 104virtual void

endDocument 101endElement 101ignorableWhitespace 101processingInstruction 101release 106resetDocument 101setDocumentLocator 102setNodeValue 105setPrefix 105setTextContent 105startDocument 102startElement 102

VSAMESDS 26KSDS 26RRDS 26

WWeb Service 38Web service 26, 28, 38, 160Web site 23, 239WebSphere Application Server 22, 31WebSphere Enterprise Service Bus 22, 32WebSphere ESB 32WebSphere Message Broker 22, 26WebSphere MQ

application 158Intercommunication 159Messaging 35

WebSphere MQ Message Broker 32WebSphere MQ See messagingWebSphere Process Server 22, 32well-formed 9whitespace 147, 188

carriage return 147horizontal tabulation 147line feed 147NEL 147newline 147

250 XML Processing Options on z/OS

Page 273: XML Processing on zOS

whole document 90Windows Notepad 154

dialog box 154file 156

WSBind 58, 107wsbind file 107

XXEH_DSOpts 224Xerces 16XLC 123XML 1–2, 17, 25, 37, 65, 86, 93, 145, 165XML 1.1 8, 147

current version 8second edition 8

XML column 83, 160XML converter 21, 30XML data 21, 26, 33, 67, 83, 151

primary use 21XML declaration 7–8, 67, 151, 230

encoding attribute 151record-specific info 230specified CCSID 153

XML document 2, 16, 26, 39, 67, 73, 95, 102, 104, 120, 122, 135, 145, 148, 168, 180, 187

basic rules 9character data 187declaration 5different encoding schemes 145encoding declaration 149event 18file 26first bytes 8HTML document 12needed information 103Other products deal 23root element 5text 87validation 10XML elements 11

xml documentlength 168

XML elementdeclaration 80

XML example 165XML flag 152XML GENERATE 45XML generation 17, 66, 89

built-in function 19capability 21code 22

XML inputstring 139

XML message 29, 107, 159XML parse 18, 66, 81, 86, 98, 106

RETURNING NATIONAL clause 81XML parser 9, 66, 86, 100, 136, 147XML parsing

built-in Java classes 143direct support 16

XML processingeligible 138model 27requirement 21–22

XML release 153, 182XML sample 6XML Schema

Language 5validation 16

XML schema 4, 16, 21, 34, 109, 111definition 5, 38, 75, 95namespace 5option 5

XML schema definition (XSD) 4–5, 95, 114element name 4file 75, 95, 114

XML standard 2XML stream 17, 66, 110, 149XML string 9, 21, 37, 66, 75, 95, 109, 116, 165

basic information 121buffer window 68String IDs 98

XML Stylesheet Language (XSL) 11XML System Service 16, 66, 86, 94, 117, 137XML to record 88XML to XML 88XML Toolkit 16, 39, 76, 88–90, 99, 136, 148

glue code 18other considerations 79Parser 16, 27, 90source offsets 79unique aspect 16XSLT Processor 17, 27, 39, 88

XML Toolkit Parser, C++ Edition 16XML Toolkit XSLT Processor, C++ Edition 16XML Transformation 11XML version 2, 103, 120, 152, 182XML4C 16XML-binary optimization Packaging (XOP) 20XMLCHAR 48XMLPARSE 18, 86, 106, 149XOP 22XPath 11, 60XPLINK 100, 133, 136XPLink 79, 88, 136Xpointer 11XQuery 11xsdosrg 122XSL 11XSLT 11XSLT Processor 80, 88, 136

Zz/FS 26z/OS specific parser class 76, 99z/OS System Services

GXL1IDI 128PIMA 73

z/OS UNIX 8, 22, 26, 66, 110, 114–115, 152, 161, 183batch interface routine 114

Index 251

Page 274: XML Processing on zOS

command line 122environment 115, 154file system 152shell 114

z/OS user 18, 90, 245z/OS V1.9 137

IBM XML Toolkit 137XML Toolkit 137

z/OS V3R3 17, 38Enterprise COBOL 17Enterprise PL/I 19

z/OS V4R2 18, 82z/OS XML 16, 66, 137, 180

data stream 223parse record stream 224parser 66, 91, 187, 202System Services 16, 27, 66, 86–88, 90–91, 94–95, 110, 113–114, 133, 137, 147–148, 163, 186–187, 245

GXL1INI 73GXL1PRS 70, 73GXL1QXD 149, 152GXL4QXD 149, 152gxluGenOSR 75GXLYQXD 152key benefit 68PIMA 66, 70, 73

System Services assembler interface 88System Services C 88System Services C/C++ APIs 79System Services combination 86System Services non-validating parsing 137System Services parse 75System Services parser 18, 69, 86, 90, 95, 117, 202System Services reason code

x1301 69–70, 119, 175x1302 70x1303 69–70, 119, 175x1304 69, 71, 119, 175

System Services return codex1302 70

System Services routine gxlprs 68System Services user 70, 149System Services user guide 152Toolkit 39, 76, 88, 99, 136, 148Toolkit XSLT processor 18See also XML Toolkit

zAAP 16, 31, 68, 76, 86, 91, 137zAAP processor 21, 138

CPU cost 140zIIP 68, 91, 137zIIP processor 22, 138

zAAP-eligible work 138

252 XML Processing Options on z/OS

Page 275: XML Processing on zOS

(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

XML Processing Options on z/OS

Page 276: XML Processing on zOS

XML Processing Options on z/OS

XML Processing Options on z/OS

Page 277: XML Processing on zOS
Page 278: XML Processing on zOS

®

SG24-7810-00 0738433780

INTERNATIONAL TECHNICALSUPPORTORGANIZATION

BUILDING TECHNICAL INFORMATION BASED ON PRACTICAL EXPERIENCE

IBM Redbooks are developed by the IBM International Technical Support Organization. Experts from IBM, Customers and Partners from around the world create timely technical information based on realistic scenarios. Specific recommendations are provided to help you implement IT solutions more effectively in your environment.

For more information:ibm.com/redbooks

®

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

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 IBM products currently implementing XML-specific features. It covers common design patterns and the products that use them. It provides 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 book focuses on z/OS and non-Java technologies and products, since there are other materials available on the Java side. Java support is largely cross-platform and not specific to z/OS.

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.

Back cover