PARSE XML

#### Search Results

Search

# PARSE XML

`PARSE XML` operand1
|  |  | `INTO` |  | `PATH` operand2 | [`NAME` operand3] | [`VALUE` operand4] |  |
| `NAME` operand3 | [`VALUE` operand4] |
| `VALUE` operand4 |  |
|  | [[`NORMALIZE`] `NAMESPACE` operand5 `PREFIX` operand6]
|  | [ `GIVING` operand7 [`SUBCODE` operand8]]
| statement...
`END-PARSE` [(r)] | (structured mode only)
`LOOP` [(r)] | (reporting mode only)

This document covers the following topics:

- PARSE XML Usage

- PARSE XML Syntax Description

- PARSE XML Examples

- PARSE XML: Reason Codes for Error Message NAT8311

For an explanation of the symbols used in the syntax diagram, see Syntax Symbols.

Related Statement: `REQUEST DOCUMENT`

Belongs to Function Group: Internet and Parsing

## PARSE XML Usage

The `PARSE XML` statement allows you to parse XML documents from a Natural program. See also Statements for Internet Access and Parsing in the Programming Guide.

It is recommended that you use dynamic variables when using the `PARSE XML` statement, because it is impossible to determine the length of a static variable. Using static variables could in turn lead to the truncation of the value that is to be written into the variable.

For information on Unicode support, see `PARSE XML` in the Unicode and Code Page Support documentation.

### Mark-Up

The following are markings used in path strings to represent the different data types in an XML document (on ASCII-based systems):

Marking | XML Data | Location in Path String
--- | --- | ---
`?` | Processing instruction (except for `<?XML...?>`) | end
`!` | Comment | end
`C` | CDATA section | end
`@` | Attribute (on z/OS: § or @, depending on session code page and terminal emulation) | before the attribute name
`/` | Closing tag and/or parent name separator in a path | end or between parent names
`$` | Parsed data - character data string | end

By using this additional markup in the path string, one can more easily identify the different elements of the XML document in the output document.

### Global Namespace

To specify the global namespace, use a colon (:) as prefix and an empty URI.

### Related System Variables

The following Natural system variables are automatically created for each `PARSE XML` statement issued:

- `*PARSE-TYPE`

- `*PARSE-LEVEL`

- `*PARSE-ROW`

- `*PARSE-COL`

- `*PARSE-NAMESPACE-URI`

The notation `(r)` after `*PARSE-TYPE`, `*PARSE-LEVEL`, `*PARSE-ROW`, `*PARSE-COL` and `*PARSE-NAMESPACE-URI` is used to indicate the label or statement number of the statement in which the `PARSE` was issued. If `(r)` is not specified, the corresponding system variable represents the system variable of the XML data currently being processed in the active `PARSE` processing loop.

For more information on these system variables, see the System Variables documentation.

## PARSE XML Syntax Description

Operand Definition Table:

Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition
--- | --- | --- | --- | ---
`operand1` | C | S |  |  |  | A | U | B |  |  |  |  |  |  |  |  |  |  | yes | no
`operand2` |  | S |  |  |  | A | U | B |  |  |  |  |  |  |  |  |  |  | yes | yes
`operand3` |  | S |  |  |  | A | U | B |  |  |  |  |  |  |  |  |  |  | yes | yes
`operand4` |  | S |  |  |  | A | U | B |  |  |  |  |  |  |  |  |  |  | yes | yes
`operand5` |  | S | A |  |  | A | U | B |  |  |  |  |  |  |  |  |  |  | yes | yes
`operand6` |  | S | A |  |  | A | U | B |  |  |  |  |  |  |  |  |  |  | yes | yes
`operand7` |  |  |  |  |  |  |  |  | I4 |  |  |  |  |  |  |  |  |  | yes | yes
`operand8` |  |  |  |  |  |  |  |  | I4 |  |  |  |  |  |  |  |  |  | yes | yes

Syntax Element Description:

Syntax Element | Description
--- | ---
`operand1` | XML Document: `operand1` represents the XML document in question. The XML document may not be changed while it is being parsed. If you try to change the XML document during parsing (by writing into it, for example), an error message will be displayed.
`PATH operand2` | Path: `operand2` represents the `PATH` of the data in the XML document. The `PATH` contains the name of the identified XML part, the names of all parents, as well as the type of the XML part. Note The information given with `PATH` can be used to easily fill a tree view. See also Example 1 - Using the PATH Option.
`NAME operand3` | Data Element Name: `operand3` represents the `NAME` of a data element in the XML document. If `NAME` has no value, then the dynamic variable associated with it will be set to `*LENGTH()=0`, which is a static variable filled with a blank. See also Example 2 - Using the NAME Option.
`VALUE operand4` | Data Element Content: `operand4` represents the content (`VALUE`) of a data element in the XML document. If there is no value, a given dynamic variable will be set to `*LENGTH()=0,` which is a static variable filled with a blank. See also Example 3 - Using the VALUE Option.
`operand5` and `operand6` `NORMALIZE NAMESPACE` `PREFIX` | Namespace URI and Prefix: The `NAMESPACE` URI or Uniform Resource Identifier (`operand5`) and the namespace `PREFIX` (`operand6`) are copied during runtime. Therefore, modifying the namespace mapping arrays inside the `PARSE XML` loop will not affect the parser. `operand5` and `operand6` are one-dimensional arrays with an equal number of occurrences. Namespace normalization is a feature of the `PARSE` statement. XML is capable of defining namespaces for the element names:
    <myns:myentity xmlns:myns="http://myuri" />
The `NAMESPACE` definition consists of two parts: a namespace `PREFIX` (which is, in this case, `myns`) and a URI (`myuri`) to define the namespace. The namespace `PREFIX` is part of the element name. This means, that for the `PARSE` statement, and especially for `operand2`, the generated `PATH` strings depend on the namespace `PREFIX`. If the path inside a Natural program is used to indicate specific tags, then this will fail if an XML document uses the correct `NAMESPACE` (URI), but with a different `PREFIX`. With namespace normalization, all namespace `PREFIX`es can be set to defaults which have been defined in the `NAMESPACE` clause. The first entry will be the one used if a URI is specified more than once. If more than one `PREFIX` is used in the XML document, then only the first one will be taken into account for the output. The rest will be ignored. The `NAMESPACE` clause contains pairs of namespace URIs and prefixes. For example:
    uri(1) := 'http://namespaces.softwareag.com/natural/demo'
    pre(1) := 'nat:'
If `NAMESPACE` is defined inside an XML document, the parser checks to see if that namespace (URI) exists in the normalization table. The prefix of the normalization table is used for all output data from the `PARSE` statement, instead of the namespace defined in the XML document. See also: Example 4 - Using the NAMESPACE Clause Example 5 - Using the NAMESPACE Clause with NORMALIZATION Additional Information Concerning PREFIX: In addition, the following applies to the prefix definition: The prefix definition in the namespace normalization array always has to end in a colon (:), since this is the string that will be replaced. A `PREFIX` or a URI may only occur once in a namespace normalization array. If a `PREFIX` or the `NAMESPACE` URI contains trailing blanks (e.g. when using a static variable), the trailing blanks will be removed before the external parser is called. If the `PREFIX` definition at the namespace normalization only contains a colon (:), the `NAMESPACE PREFIX` will be reduced to a colon (:). If the `PREFIX` definition at the namespace normalization is empty, then the `NAMESPACE PREFIX` will be deleted.
`GIVING operand7` | GIVING: When the `PARSE` process encounters an error at runtime, `operand7` holds the 4-digit Natural error number. `Operand7` is updated at the end of each iteration in a parse process. `GIVING` applies only to error code NAT8311. If the `GIVING` parameter is specified, `operand7` returns `0` in the absence of an error. However, if a `PARSE` error occurs, `operand7` returns an appropriate Natural error number. When an error occurs and the `GIVING` parameter is specified, the `PARSE` loop is terminated and control is passed back to the statement following `END-PARSE`. When `GIVING` is not set and an error occurs, a Natural error message is returned and program execution is suspended, unless the `ON ERROR` statement block is used. See also Example 6 - Using the GIVING and SUBCODE Clauses.
`SUBCODE operand8` | SUBCODE: When the `PARSE` process encounters an error at runtime, `operand8` holds the 3-digit Reason Code associated with the error number in `operand7`. `Operand8` is updated at the end of each iteration in a parse process. If `SUBCODE` parameter is specified, `operand8` returns `0` in the absence of an error. However, if a `PARSE` error occurs, `operand8` returns an appropriate reason code. `SUBCODE` applies only to error code NAT8311. When the `SUBCODE` operand is provided along with `GIVING` and an error occurs, the `PARSE` loop is terminated and control is returned to the statement following `END-PARSE`. Note You can find the list of all reason codes for Natural error NAT8311 related to `PARSE XML` under PARSE XML: Reason Codes for Error Message NAT8311. See also Example 6 - Using the GIVING and SUBCODE Clauses.
`END-PARSE (r)` | End of PARSE XML Statement: In structured mode, the Natural reserved keyword `END-PARSE` must be used to end the `PARSE XML` statement. You can specify labels or line numbers with `END-PARSE` in structured mode. In reporting mode, the Natural statement `LOOP` is used to end the `PARSE XML` statement. You can specify labels or line numbers with `LOOP` in reporting mode.
`LOOP (r)`

## PARSE XML Examples

- Example 1 - Using the PATH Option

- Example 2 - Using the NAME Option

- Example 3 - Using the VALUE Option

- Example 4 - Using the NAMESPACE Clause

- Example 5 - Using the NAMESPACE Clause with NORMALIZATION

- Example 6 - Using the GIVING and SUBCODE Clauses

### Example 1 - Using the PATH Option

The following code:

    ** Example 'PAXMLEX1': PARSE XML (with PATH and CODEPAGE)
    **
    ************************************************************************
    DEFINE DATA LOCAL
    1 MYXML     (A) DYNAMIC
    1 MYPATH    (A) DYNAMIC
    END-DEFINE
    *
    COMPRESS '<?xml version="1.0"  ?>'
             '<employee personnel-id="30016315" >'
             '<full-name>'
             '<!--this is just a comment-->'
             '<first-name>RICHARD</first-name>'
             '<name>FORDHAM</name>'
             '</full-name>'
             '</employee>'
    INTO MYXML LEAVING NO
    *
    PARSE XML MYXML INTO PATH MYPATH
       PRINT MYPATH
    END-PARSE
    END

produces the following output:

    employee
    employee/@personnel-id
    employee/full-name
    employee/full-name/!
    employee/full-name/first-name
    employee/full-name/first-name/$
    employee/full-name/first-name//
    employee/full-name/name
    employee/full-name/name/$
    employee/full-name/name//
    employee/full-name//
    employee//

### Example 2 - Using the NAME Option

The following code:

    ** Example 'PAXMLEX2': PARSE XML (with PATH and NAME)
    **
    ************************************************************************
    DEFINE DATA LOCAL
    1 MYXML       (A) DYNAMIC
    1 MYPATH      (A) DYNAMIC
    1 MYNAME      (A) DYNAMIC
    END-DEFINE
    *
    COMPRESS '<?xml version="1.0"  ?>'
             '<employee personnel-id="30016315" >'
             '<full-name>'
             '<!--this is just a comment-->'
             '<first-name>RICHARD</first-name>'
             '<name>FORDHAM</name>'
             '</full-name>'
             '</employee>'
    INTO MYXML LEAVING NO
    *
    PARSE XML MYXML INTO PATH MYPATH NAME MYNAME
       DISPLAY (AL=39) MYPATH MYNAME
    END-PARSE
    END

produces the following output:

                   MYPATH                                MYNAME
    ----------------------------------    -----------------------------------

    employee                              employee
    employee/@personnel-id                personnel-id
    employee/full-name                    full-name
    employee/full-name/!
    employee/full-name/first-name         first-name
    employee/full-name/first-name/$
    employee/full-name/first-name//       first-name
    employee/full-name/name               name
    employee/full-name/name/$
    employee/full-name/name//             name
    employee/full-name//                  full-name
    employee//                            employee

### Example 3 - Using the VALUE Option

The following code:

    ** Example 'PAXMLEX3': PARSE XML (with PATH and VALUE)
    **
    ************************************************************************
    DEFINE DATA LOCAL
    1 MYXML       (A) DYNAMIC
    1 MYPATH      (A) DYNAMIC
    1 MYVALUE     (A) DYNAMIC
    END-DEFINE
    *
    COMPRESS '<?xml version="1.0"  ?>'
             '<employee personnel-id="30016315" >'
             '<full-name>'
             '<!--this is just a comment-->'
             '<first-name>RICHARD</first-name>'
             '<name>FORDHAM</name>'
             '</full-name>'
             '</employee>'
    INTO MYXML LEAVING NO
    *
    PARSE XML MYXML INTO PATH MYPATH VALUE MYVALUE
       DISPLAY (AL=39) MYPATH MYVALUE
    END-PARSE
    END

produces the following output:

                  MYPATH                                MYVALUE
    ----------------------------------    -----------------------------------

    employee
    employee/@personnel-id                30016315
    employee/full-name
    employee/full-name/!                  this is just a comment
    employee/full-name/first-name
    employee/full-name/first-name/$       RICHARD
    employee/full-name/first-name//
    employee/full-name/name
    employee/full-name/name/$             FORDHAM
    employee/full-name/name//
    employee/full-name//
    employee//

### Example 4 - Using the NAMESPACE Clause

The following XML code:

    myxml := '<?xml version="1.0" encoding="ISO-8859-1" ?>'-
             '<nat:employee nat:personnel-id="30016315"'-
             ' xmlns:nat="http://namespaces.softwareag.com/natural/demo">'-
             '<nat:full-Name>'-
             '<nat:first-name>RICHARD</nat:first-name>'-
             '<nat:name>FORDHAM</nat:name>'-
             '</nat:full-Name>'-
             '</nat:employee>'

processed by the following Natural code:

    PARSE XML myxml INTO PATH mypath
      PRINT mypath
    END-PARSE

produces the following output:

    nat:employee
    nat:employee/@nat:personnel-id
    nat:employee/@xmlns:nat
    nat:employee/nat:full-Name
    nat:employee/nat:full-Name/nat:first-name
    nat:employee/nat:full-Name/nat:first-name/$
    nat:employee/nat:full-Name/nat:first-name//
    nat:employee/nat:full-Name/nat:name
    nat:employee/nat:full-Name/nat:name/$
    nat:employee/nat:full-Name/nat:name//
    nat:employee/nat:full-Name//
    nat:employee//

### Example 5 - Using the NAMESPACE Clause with NORMALIZATION

Using `NORMALIZE NAMESPACE`, the same XML document as in Example 4 with a different `NAMESPACE PREFIX` produces the same output.

XML code:

    myxml := '<?xml version="1.0" encoding="ISO-8859-1" ?>'-
             '<natural:employee natural:personnel-id="30016315"'-
             ' xmlns:natural="http://namespaces.softwareag.com/natural/demo">'-
             '<natural:full-Name>'-
             '<natural:first-name>RICHARD</natural:first-name>'-
             '<natural:name>FORDHAM</natural:name>'-
             '</natural:full-Name>'-
             '</natural:employee>'

Natural code:

    uri(1) := 'http://namespaces.softwareag.com/natural/demo'
    pre(1) := 'nat:'
    *
    PARSE XML myxml INTO PATH mypath NORMALIZE NAMESPACE uri(*) PREFIX pre(*)
      PRINT mypath
    END-PARSE

Output of the program:

    nat:employee
    nat:employee/@nat:personnel-id
    nat:employee/@xmlns:nat
    nat:employee/nat:full-Name
    nat:employee/nat:full-Name/nat:first-name
    nat:employee/nat:full-Name/nat:first-name/$
    nat:employee/nat:full-Name/nat:first-name//
    nat:employee/nat:full-Name/nat:name
    nat:employee/nat:full-Name/nat:name/$
    nat:employee/nat:full-Name/nat:name//
    nat:employee/nat:full-Name//
    nat:employee//

### Example 6 - Using the GIVING and SUBCODE Clauses

The following program produces a runtime error:

    ** Example 'PAXMLEX4': PARSE XML (with GIVING and SUBCODE)
    **
    ************************************************************************
    DEFINE DATA LOCAL
    1 MYXML     (A) DYNAMIC
    1 MYPATH    (A) DYNAMIC
    1 MYNAME    (A) DYNAMIC
    1 MYVALUE   (A) DYNAMIC
    1 MYGIVING  (I4)
    1 MYSUBCODE (I4)
    END-DEFINE
    *
    * Produce Natural runtime error with incorrect XML document
    *
    COMPRESS '<?xml version="1.0"  ?>'
             '<employee personnel-id="30016315" >'
             '<full-name>'
             '<!--this is just a comment-->'
             '<first-name>RICHARD</first>'  /* here the key 'first' is wrong
             '<name>FORDHAM</name>'
             '</full-name>'
             '</employee>'
    INTO MYXML LEAVING NO
    *
    PARSE XML MYXML INTO PATH MYPATH NAME MYNAME VALUE MYVALUE
                         GIVING MYGIVING SUBCODE MYSUBCODE
       WRITE (AL=39) MYPATH
    END-PARSE
    *
    IF MYGIVING NE 0
      WRITE / 'Error Number:'  MYGIVING 'Subcode:' MYSUBCODE
    END-IF
    END

produces the following output:

    employee
    employee/@personnel-id
    employee/full-name
    employee/full-name/!
    employee/full-name/first-name

    Error Number:        8311 Subcode:         225

## PARSE XML: Reason Codes for Error Message NAT8311

If the XML parsing process terminates with error message NAT8311, the XML input document is syntactically invalid. The reason codes returned, along with NAT8311, represent the following meanings:

##### Reason Codes for Error Message NAT8311

Reason Code | Explanation
--- | ---
201 | Entity expansion limit exceeded during XML parsing.
202 | Comment or CDATA section is expected.
203 | Attribute name is expected.
204 | Notation name is expected.
205 | Illegal repetition of elements in mixed content model.
206 | Default attribute declaration is expected.
207 | Equal sign is expected.
208 | Element name is expected.
209 | Comment must start with `<!--`.
210 | Invalid document structure.
211 | Version, encoding, or standalone declaration is expected .
212 | Invalid XML version declaration.
213 | Unsupported XML version.
214 | Unterminated XML declaration.
215 | Invalid XML encoding declaration.
216 | Invalid standalone declaration.
217 | Unterminated comment.
218 | Processing instruction name is expected.
219 | Unterminated processing instruction.
220 | Invalid character.
221 | Unterminated start tag.
222 | Attribute value is expected.
223 | Unterminated end tag.
224 | Type mismatch for attribute of element is expected.
225 | End of tag is expected.
226 | Tag name, comment, PI, or other markup expected.
227 | Invalid content after the end tag of a root element.
228 | Comment is expected.
229 | Comment or processing instruction is expected.
230 | Whitespace is expected.
231 | Root element in `DOCTYPE` declaration is expected.
232 | Quoted string is expected.
233 | Public ID is expected.
234 | Invalid character in public ID.
235 | Unterminated `DOCTYPE` declaration.
236 | Invalid character in internal subset.
237 | Unexpected whitespace.
238 | Invalid character in attribute value.
239 | Markup declaration is expected.
240 | `TEXT` declaration is illegal at this point.
241 | Conditional section in internal subset.
242 | Parameter entity name is expected.
243 | Unterminated entity declaration.
244 | Invalid character reference.
245 | Unterminated character reference.
246 | Entity name for reference expected.
247 | Entity not found.
248 | Unparsed entity reference is invalid at this point.
249 | Unterminated entity reference.
250 | Recursive entity expansion.
251 | Partial markup in entity value.
252 | Unterminated element declaration.
253 | Content specification for element is expected.
254 | `'*'` is expected.
255 | Mixed content model not terminated properly.
256 | System or public ID is expected.
257 | Unterminated notation declaration.
258 | `','`, `'|'`, or `')'` is expected.
259 | `'|'` or `')'` is expected.
260 | `','`, `'|'`, or `')'` is expected in content model of element.
261 | Enumeration value for attribute is expected.
262 | `'|'` or `')'` is expected.
263 | Unterminated entity literal.
264 | Unmatched end tag detected.
265 | `'('` is expected.
266 | Attribute is already specified for element.
267 | `'<'` character cannot be used in attribute value. You must use `<` instead.
268 | Leading surrogate character is not followed by a legal second character.
269 | `']]>'` sequence to end conditional section is expected.
270 | `INCLUDE` or `IGNORE` at this point is expected.
271 | `'['` following `INCLUDE` or `IGNORE` is expected.
272 | Unexpected end of entity.
273 | Parameter entity propagated out of internal or external subset.
274 | Unmatched ']' character detected.
275 | Parameter entity references are not allowed inside markup in internal subset.
276 | Entity propagated out of the content section into miscellaneous.
277 | Expected `&#` to be followed by a numeric character value.
278 | `'['` expected.
279 | `']]>'` sequence is not allowed in character data.
280 | `'--'` sequence is illegal in comment.
281 | Unterminated CDATA section.
282 | NDATA expected.
283 | NDATA is illegal for parameter entities.
284 | Hex radix character references must use `'x'`, not `'X'`.
285 | Declaration already seen.
286 | XML declarations must be in this order: version, encoding, standalone.
287 | External entity cannot be referred to from attribute value.
288 | Illegal Xerces Condition.
289 | Conflict in namespace definition and namespace mapping table.
290 | Syntax Error.

### On this page

- PARSE XML Usage
- PARSE XML Syntax Description
- PARSE XML Examples
- PARSE XML: Reason Codes for Error Message NAT8311