Skip Headers

Oracle® Application Developer's Guide - XML 10g (9.0.4) Part Number B12099-01 |
Home | Contents | Index

# 24
Using XML Parser for C

This chapter contains the following sections:

- Accessing XML Parser for C

- XML Parser for C Features

- XML Parser for C Usage

- XML Parser for C, XSLT (DOM Interface) Usage

- XML Parser for C, Default Behavior

- DOM and SAX APIs

- Invoking XML Parser for C

- Using the Sample Files Included with Your Software

- Running the XML Parser for C Sample Programs

## Accessing XML Parser for C

XML Parser for C is provided with Oracle and Oracle Application Server. It is also available for download from the OTN site: http://otn.oracle.com/tech/xml

It is located in`$ORACLE_HOME/xdk/c/parser`.

## XML Parser for C Features

`readme.html` in the root directory of the software archive contains release specific information including bug fixes and API additions.

XML Parser for C will check if an XML document is well-formed, and optionally validate it against a DTD. The parser constructs an object tree which can be accessed through a DOM interface or operate serially via a SAX interface.

You can post questions, comments, or bug reports to the XML Discussion Forum at http://otn.oracle.com/tech/xml.

### Specifications

See Appendix E, "XDK for C: Specifications and Cheat Sheets" for a brief list of XML Parser for C methods and specifications.

See Also: The doc directory in your install area Oracle9i XML Reference On OTN under http://otn.oracle.com/tech/xml/

### Memory Allocation

The memory callback functions `memcb` may be used if you wish to use your own memory allocation. If they are used, all of the functions should be specified.

The memory allocated for parameters passed to the SAX callbacks or for nodes and data stored with the DOM parse tree will not be freed until one of the following is done:

- `xmlparse()` or`xmlparsebuf()` is called to parse another file or buffer.

- `xmlclean()` is called.

- `xmlterm()` is called.

### Thread Safety

If threads are forked off somewhere in the midst of the init-parse-term sequence of calls, you will get unpredictable behavior and results.

### Data Types Index

Table 24-1 lists the datatypes used in XML Parser for C.

##### Table 24-1 Datatypes Used in XML Parser for C

DataType | Description
--- | ---
oratext | String pointer
xmlctx | Master XML context
xmlmemcb | Memory callback structure (optional)
xmlsaxcb | SAX callback structure (SAX only)
ub4 | 32-bit (or larger) unsigned integer
uword | Native unsigned integer

### Error Message Files

Error message files are provided in the mesg/ subdirectory. The messages files also exist in the `$ORACLE_HOME/oracore/mesg` directory. You may set the environment variable `ORA_XML_MESG` to point to the absolute path of the `mesg/` subdirectory although this not required.

### Validation Modes

Available validation modes are described in Chapter 20, "Using XML Parser for Java", "Oracle XML Parsers Support Four Validation Modes" .

## XML Parser for C Usage

Figure 24-1 describes XML Parser for C calling sequence as follows:

1. `XMLinit()` function initializes the parsing process.

2. The parsed item can be an XML document (file) or string buffer. If the input is an XML document or file, it is parsed using the `xmlparser()` function. If the input is a string buffer, it is parsed using the `xmlparserbuf()` function.

3. DOM or SAX API:

   DOM: If you are using the DOM interface, include the following steps:

   - The `xmlparse()` or `xmlparseBuffer()` function calls `.getDocumentElement()`. If no other DOM functions are being applied, you can invoke `xmlterm()`.

   - This optionally calls other DOM functions if required. These are typically Node or print functions. It outputs the DOM document.

   - If complete, the process invokes `xmlterm()`

   - You can optionally first invoke `xmlclean()` to clean up any data structures created during the parse process. You would then call `xmlterm()`

   SAX: If you are using the SAX interface, include the following steps:

   - Process the results of the parser from `xmlparse()` or `xmlparseBuf()` using callback functions.

   - Register the callback functions.

4. Optionally, use`xmlclean()` to clean up the memory and structures used during a parse, and go to Step 5. or return to Step 2.

5. Terminate the parsing process with `xmlterm()`

XML Parser for C usage is further explained in Figure 24-1.

#### Parser Calling Sequence

The sequence of calls to the parser can be any of the following:

- `xmlinit() - xmlparse()` or

  `xmlparsebuf() - xmlterm()`

- `xmlinit() - xmlparse()` or

  `xmlparsebuf() - xmlclean() - xmlparse()` or

  `xmlparsebuf() - xmlclean() -... - xmlterm()`

- `xmlinit() - xmlparse()` or

  `xmlparsebuf() - xmlparse()` or

  `xmlparsebuf() -... - xmlterm()`

#### Figure 24-1 XML Parser for C Calling Sequence

Text description of the illustration adxml096.gif

## XML Parser for C, XSLT (DOM Interface) Usage

Figure 24-2 shows the XML Parser for C, XSLT functionality.

1. There are two inputs to `xmlparse()`:

   - The Stylesheet to be applied to the XML document

   - XML document

   The output of `xmlparse()`, the parsed stylesheet and parsed XML document, are sent to the `xslprocess()` function for processing.

2. `xmlinit()` initializes the XSLT processing. `xmlinit()` initializes the `xslprocess()` result

3. `xslprocess()o`ptionally calls other functions, such as print functions. You can see the list of available functions either on OTN or in the Oracle9i XML Reference.

4. The resultant document (XML, HTML, VML, and so on) is typically sent to an application for further processing.

5. The application terminates the XSLT process by declaring `xmlterm()`, for the XML document, stylesheet, and final result.

XML Parser for C's XSLT functionality is illustrated with the following examples:

- XML Parser for C Example 16: C -- XSLSample.c

- XML Parser for C Example 17: C -- XSLSample.std

#### Figure 24-2 XML Parser for C: XSLT (DOM Interface) Usage

Text description of the illustration adxml056.gif

## XML Parser for C, Default Behavior

The following is the XML Parser for C default behavior:

- Character set encoding is UTF-8. If all your documents are ASCII, you are encouraged to set the encoding to US-ASCII for better performance.

- Messages are printed to stderr unless msghdlr is given.

- A parse tree which can be accessed by DOM APIs is built unless saxcb is set to use the SAX callback APIs. Note that any of the SAX callback functions can be set to NULL if not needed.

- The default behavior for the parser is to check that the input is well-formed but not to check whether it is valid. The flag XML_FLAG_VALIDATE can be set to validate the input. The default behavior for whitespace processing is to be fully conformant to the XML 1.0 spec, that is, all whitespace is reported back to the application but it is indicated which whitespace is ignorable. However, some applications may prefer to set the XML_FLAG_DISCARD_WHITESPACE which will discard all whitespace between an end-element tag and the following start-element tag.

  Note: It is recommended that you set the default encoding explicitly if using only single byte character sets (such as US-ASCII or any of the ISO-8859 character sets) for performance up to 25% faster than with multibyte character sets, such as UTF-8.

## DOM and SAX APIs

Oracle XML parser for C checks if an XML document is well-formed, and optionally validates it against a DTD. The parser constructs an object tree which can be accessed via one of the following interfaces:

- DOM interface

- Serially via a SAX interface

These two XML APIs:

- DOM: Tree-based APIs. A tree-based API compiles an XML document into an internal tree structure, then allows an application to navigate that tree using the Document Object Model (DOM), a standard tree-based API for XML and HTML documents.

- SAX: Event-based APIs. An event-based API, on the other hand, reports parsing events (such as the start and end of elements) directly to the application through callbacks, and does not usually build an internal tree. The application implements handlers to deal with the different events, much like handling events in a graphical user interface.

Tree-based APIs are useful for a wide range of applications, but they often put a great strain on system resources, especially if the document is large (under very controlled circumstances, it is possible to construct the tree in a lazy fashion to avoid some of this problem). Furthermore, some applications need to build their own, different data trees, and it is very inefficient to build a tree of parse nodes, only to map it onto a new tree.

In both of these cases, an event-based API provides a simpler, lower-level access to an XML document: you can parse documents much larger than your available system memory, and you can construct your own data structures using your callback event handlers.

### Using the SAX API

To use SAX, an `xmlsaxcb` structure is initialized with function pointers and passed to the `xmlinit()` call. A pointer to a user-defined context structure can also be included. That context pointer will be passed to each SAX function.

#### SAX Callback Structure

The SAX callback structure:

    typedef struct
    {
     sword (*startDocument)(void *ctx);
     sword (*endDocument)(void *ctx);
     sword (*startElement)(void *ctx, const oratext *name,
                 const struct xmlarray *attrs);
     sword (*endElement)(void *ctx, const oratext *name);
     sword (*characters)(void *ctx, const oratext *ch, size_t len);
     sword (*ignorableWhitespace)(void *ctx, const oratext *ch, size_t len);
     sword (*processingInstruction)(void *ctx, const oratext *target,
                 const oratext *data);
     sword (*notationDecl)(void *ctx, const oratext *name,
                 const oratext *publicId, const oratext *systemId);
     sword (*unparsedEntityDecl)(void *ctx, const oratext *name,
                 const oratext *publicId,
                 const oratext *systemId, const oratext *notationName);
     sword (*nsStartElement)(void *ctx, const oratext *qname,
                 const oratext *local, const oratext *nsp,
                 const struct xmlnodes *attrs);
    } xmlsaxcb;

### Using the DOM API

See "XML Parser for C Example 7: C -- DOMSample.std" .

## Invoking XML Parser for C

XML Parser for C can be invoked in two ways:

- By invoking the executable on the command line

- By writing C code and using the supplied APIs

### Command Line Usage

The XML Parser for C can be called as an executable by invoking `bin/xml`

Table 24-2 lists the command line options.

##### Table 24-2 XML Parser for C: Command Line Options

Option | Description
--- | ---
-c | Conformance check only, no validation
-e encoding | Specify input file encoding
-h | Help - show this usage help
-n | Number - DOM traverse and report number of elements
-p | Print document and DTD structures after parse
-x | Exercise SAX interface and print document
-v | Version - display parser version then exit
-w | Whitespace - preserve all whitespace

### Writing C Code to Use Supplied APIs

XML Parser for C can also be invoked by writing code to use the supplied APIs. The code must be compiled using the headers in the include/ subdirectory and linked against the libraries in the lib/ subdirectory. Please see the `Makefile` in the sample/ subdirectory for full details of how to build your program.

## Using the Sample Files Included with Your Software

$ORACLE_HOME/xdk/c/parser/`sample/` directory contains several XML applications to illustrate how to use the XML Parser for C with the DOM and SAX interfaces.

Table 24-3 lists the sample files in sample/ directory.

##### Table 24-3 XML Parser for C sample/ Files

sample/ File Name | Description
--- | ---
DOMNamespace.c | Source for DOMNamespace program
DOMNamespace.std | Expected output from DOMNamespace
DOMSample.c | Source for DOMSample program
DOMSample.std | Expected output from DOMSample
FullDOM.c | Sample usage of DOM interface
FullDOM.std | Expected output from FullDOM
Make.bat | Batch file for building sample programs
NSExample.xml | Sample XML file using namespaces
SAXNamespace.c | Source for SAXNamespace program
SAXNamespace.std | Expected output from SAXNamespace
SAXSample.c | Source for SAXSample program
SAXSample.std | Expected output from SAXSample
XSLSample.c | Source for XSLSample program
XSLSample.std | Expected output from XSLSample
class.xml | XML file that may be used with XSLSample
iden.xsl | Stylesheet that may be used with XSLSample
cleo.xml | The Tragedy of Antony and Cleopatra XML version of Shakespeare's play

--

## Running the XML Parser for C Sample Programs

### Building the Sample programs

Change directories to ..sample/ and read the README file. This will explain how to build the sample programs according to your platform.

### Sample Programs

Table 24-4 lists the programs built by the sample files in sample/

##### Table 24-4 XML Parser for C: Sample Built Programs in sample/

Built Program | Description
--- | ---
DOMSample | A sample application using DOM APIs (shows an outline of Cleopatra, i.e. the XML elements ACT and SCENE).
SAXSample [word] | A sample application using SAX APIs. Given a word, shows all lines in the play Cleopatra containing that word. If no word is specified, 'death' is used.
DOMNamespace | Same as SAXNamespace except using DOM interface.
SAXNamespace | A sample application using Namespace extensions to SAX API; prints out all elements and attributes of NSExample.xml along with full namespace information.
FullDOM | Sample usage of full DOM interface. Exercises all the calls, but does nothing too exciting.
XSLSample <xmlfile> <xsl ss> | Sample usage of XSL processor. It takes two filenames as input, the XML file and XSL stylesheet

### XML Parser for C Example 1: XML -- class.xml

`class.xml` is an XML file that inputs XSLSample.c.

    <?xml version = "1.0"?>
    <!DOCTYPE course [
    <!ELEMENT course (Name, Dept, Instructor, Student)>
    <!ELEMENT Name (#PCDATA)>
    <!ELEMENT Dept (#PCDATA)>
    <!ELEMENT Instructor (Name)>
    <!ELEMENT Student (Name*)>
    ]>
    <course>
    <Name>Calculus</Name>
    <Dept>Math</Dept>
    <Instructor>
    <Name>Jim Green</Name>
    </Instructor>
    <Student>
    <Name>Jack</Name>
    <Name>Mary</Name>
    <Name>Paul</Name>
    </Student>
    </course>

### XML Parser for C Example 2: XML -- cleo.xml

This XML example inputs `DOMSample.c` and `SAXSample.c`.

    <?xml version="1.0"?>
    <!DOCTYPE PLAY [
        <!ELEMENT PLAY     (TITLE, PERSONAE, SCNDESCR, PLAYSUBT, INDUCT?,
    						 PROLOGUE?, ACT+, EPILOGUE?)>
        <!ELEMENT TITLE    (#PCDATA)>
        <!ELEMENT FM       (P+)>
        <!ELEMENT P        (#PCDATA)>
        <!ELEMENT PERSONAE (TITLE, (PERSONA | PGROUP)+)>
        <!ELEMENT PGROUP   (PERSONA+, GRPDESCR)>
        <!ELEMENT PERSONA  (#PCDATA)>
        <!ELEMENT GRPDESCR (#PCDATA)>
        <!ELEMENT SCNDESCR (#PCDATA)>
        <!ELEMENT PLAYSUBT (#PCDATA)>
        <!ELEMENT INDUCT   (TITLE, SUBTITLE*, (SCENE+|(SPEECH|STAGEDIR|SUBHEAD)+))>
        <!ELEMENT ACT      (TITLE, SUBTITLE*, PROLOGUE?, SCENE+, EPILOGUE?)>
        <!ELEMENT SCENE    (TITLE, SUBTITLE*, (SPEECH | STAGEDIR | SUBHEAD)+)>
        <!ELEMENT PROLOGUE (TITLE, SUBTITLE*, (STAGEDIR | SPEECH)+)>
        <!ELEMENT EPILOGUE (TITLE, SUBTITLE*, (STAGEDIR | SPEECH)+)>
        <!ELEMENT SPEECH   (SPEAKER+, (LINE | STAGEDIR | SUBHEAD)+)>
        <!ELEMENT SPEAKER  (#PCDATA)>
        <!ELEMENT LINE     (#PCDATA | STAGEDIR)*>
        <!ELEMENT STAGEDIR (#PCDATA)>
        <!ELEMENT SUBTITLE (#PCDATA)>
        <!ELEMENT SUBHEAD  (#PCDATA)>
    ]>

    <PLAY>
    <TITLE>The Tragedy of Antony and Cleopatra</TITLE>

    <PERSONAE>
    <TITLE>Dramatis Personae</TITLE>

    <PGROUP>
    <PERSONA>MARK ANTONY</PERSONA>
    <PERSONA>OCTAVIUS CAESAR</PERSONA>
    <PERSONA>M. AEMILIUS LEPIDUS</PERSONA>
    <GRPDESCR>triumvirs.</GRPDESCR>
    </PGROUP>

    <PERSONA>SEXTUS POMPEIUS</PERSONA>

    <PGROUP>
    <PERSONA>DOMITIUS ENOBARBUS</PERSONA>
    <PERSONA>VENTIDIUS</PERSONA>
    <PERSONA>EROS</PERSONA>
    <PERSONA>SCARUS</PERSONA>
    <PERSONA>DERCETAS</PERSONA>
    <PERSONA>DEMETRIUS</PERSONA>
    <PERSONA>PHILO</PERSONA>
    <GRPDESCR>friends to Antony.</GRPDESCR>
    </PGROUP>

    <PGROUP>
    <PERSONA>MECAENAS</PERSONA>
    <PERSONA>AGRIPPA</PERSONA>
    <PERSONA>DOLABELLA</PERSONA>
    <PERSONA>PROCULEIUS</PERSONA>
    <PERSONA>THYREUS</PERSONA>
    <PERSONA>GALLUS</PERSONA>
    <PERSONA>MENAS</PERSONA>
    <GRPDESCR>friends to Caesar.</GRPDESCR>
    </PGROUP>

    ...
    ...

    <SCNDESCR>SCENE  In several parts of the Roman empire.</SCNDESCR>

    <PLAYSUBT>ANTONY AND CLEOPATRA</PLAYSUBT>

    <ACT><TITLE>ACT I</TITLE>

    <SCENE><TITLE>SCENE I.  Alexandria. A room in CLEOPATRA's palace.</TITLE>
    <STAGEDIR>Enter DEMETRIUS and PHILO</STAGEDIR>

    <SPEECH>
    <SPEAKER>PHILO</SPEAKER>
    <LINE>Nay, but this dotage of our general's</LINE>
    <LINE>O'erflows the measure: those his goodly eyes,</LINE>
    <LINE>That o'er the files and musters of the war</LINE>
    <LINE>Have glow'd like plated Mars, now bend, now turn,</LINE>
    <LINE>The office and devotion of their view</LINE>
    <LINE>Upon a tawny front: his captain's heart,</LINE>
    <LINE>Which in the scuffles of great fights hath burst</LINE>
    <LINE>The buckles on his breast, reneges all temper,</LINE>
    <LINE>And is become the bellows and the fan</LINE>
    <LINE>To cool a gipsy's lust.</LINE>
    <STAGEDIR>Flourish. Enter ANTONY, CLEOPATRA, her Ladies,
    the Train, with Eunuchs fanning her</STAGEDIR>
    <LINE>Look, where they come:</LINE>
    <LINE>Take but good note, and you shall see in him.</LINE>
    <LINE>The triple pillar of the world transform'd</LINE>
    <LINE>Into a strumpet's fool: behold and see.</LINE>
    </SPEECH>

    <SPEECH>
    <SPEAKER>CLEOPATRA</SPEAKER>
    <LINE>If it be love indeed, tell me how much.</LINE>
    </SPEECH>

    <SPEECH>
    <SPEAKER>MARK ANTONY</SPEAKER>
    <LINE>There's beggary in the love that can be reckon'd.</LINE>
    </SPEECH>

    <SPEECH>
    <SPEAKER>CLEOPATRA</SPEAKER>
    <LINE>I'll set a bourn how far to be beloved.</LINE>
    </SPEECH>

    <SPEECH>
    <SPEAKER>MARK ANTONY</SPEAKER>
    <LINE>Then must thou needs find out new heaven, new earth.</LINE>
    </SPEECH>
    ...
    ...
    ...
    <SPEAKER>DOLABELLA</SPEAKER>
    <LINE>Here, on her breast,</LINE>
    <LINE>There is a vent of blood and something blown:</LINE>
    <LINE>The like is on her arm.</LINE>
    </SPEECH>

    <SPEECH>
    <SPEAKER>First Guard</SPEAKER>
    <LINE>This is an aspic's trail: and these fig-leaves</LINE>
    <LINE>Have slime upon them, such as the aspic leaves</LINE>
    <LINE>Upon the caves of Nile.</LINE>
    </SPEECH>

    <SPEECH>
    <SPEAKER>OCTAVIUS CAESAR</SPEAKER>
    <LINE>Most probable</LINE>
    <LINE>That so she died; for her physician tells me</LINE>
    <LINE>She hath pursued conclusions infinite</LINE>
    <LINE>Of easy ways to die. Take up her bed;</LINE>
    <LINE>And bear her women from the monument:</LINE>
    <LINE>She shall be buried by her Antony:</LINE>
    <LINE>No grave upon the earth shall clip in it</LINE>
    <LINE>A pair so famous. High events as these</LINE>
    <LINE>Strike those that make them; and their story is</LINE>
    <LINE>No less in pity than his glory which</LINE>
    <LINE>Brought them to be lamented. Our army shall</LINE>
    <LINE>In solemn show attend this funeral;</LINE>
    <LINE>And then to Rome. Come, Dolabella, see</LINE>
    <LINE>High order in this great solemnity.</LINE>
    </SPEECH>

    <STAGEDIR>Exeunt</STAGEDIR>
    </SCENE>
    </ACT>
    </PLAY>

### XML Parser for C Example 3: XSL -- iden.xsl

This example stylesheet can be used to input `XSLSample.c`.

    <?xml version="1.0"?>
    <!-- Identity transformation -->
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

      <xsl:template match="*|@*|comment()|processing-instruction()|text()">
          <xsl:copy>
              <xsl:apply-templates
    select="*|@*|comment()|processing-instruction()|text()"/>
          </xsl:copy>
      </xsl:template>

    </xsl:stylesheet>

### XML Parser for C Example 4: XML -- FullDOM.xml (DTD)

This DTD example inputs `FullDOM.c`.

    <!DOCTYPE doc [
        <!ELEMENT p (#PCDATA)>
        <!ATTLIST p xml:space (preserve|default) 'preserve'>
        <!NOTATION notation1 SYSTEM "file.txt">
        <!NOTATION notation2 PUBLIC "some notation">
        <!ELEMENT doc (p*)>
        <!ENTITY example "<p>An ampersand (&#38;#38;) may be escaped
    numerically (&#38;#38;#38;) or with a general entity
    (&amp;amp;).</p>">
    ]>
    <doc xml:lang="foo">&example;</doc>

### XML Parser for C Example 5: XML -- NSExample.xml

The following example file, `NSExample.xml`, uses namespaces.

    <!DOCTYPE doc [
    <!ELEMENT doc (child*)>
    <!ATTLIST doc xmlns:nsprefix CDATA #IMPLIED>
    <!ATTLIST doc xmlns CDATA #IMPLIED>
    <!ATTLIST doc nsprefix:a1 CDATA #IMPLIED>
    <!ELEMENT child (#PCDATA)>
    ]>
    <doc nsprefix:a1 = "v1" xmlns="http://www.w3c.org"
    xmlns:nsprefix="http://www.oracle.com">
    <child>
    This element inherits the default Namespace of doc.
    </child>
    </doc>

### XML Parser for C Example 6: C -- DOMSample.c

This example contains the C source code for `DOMSample.c`

    /* Copyright (c) Oracle Corporation 1999. All Rights Reserved. */
    /*
       NAME
         DOMSample.c - Sample DOM usage
       DESCRIPTION
         Sample usage of C XML parser via DOM interface
    */

    #include <stdio.h>

    #ifndef ORATYPES
    # include <oratypes.h>
    #endif
    #ifndef ORAXML_ORACLE
    # include <oraxml.h>
    #endif

    #define DOCUMENT        (oratext *) "cleo.xml"

    void dump(xmlctx *ctx, xmlnode *node);
    void dumppart(xmlctx *ctx, xmlnode *node, boolean indent);

    int main()
    {
        xmlctx     *ctx;
        uword       ecode;

        puts("XML C DOM sample");
        puts("Initializing XML package...");
        if (!(ctx = xmlinit(&ecode, (const oratext *) 0,
                            (void (*)(void *, const oratext *, uword)) 0,
                            (void *) 0, (const xmlsaxcb *) 0, (void *) 0,
    			(const xmlmemcb *) 0, (void *) 0,
                            (const oratext *) 0)))
        {
    	printf("Failed to initialze XML parser, error %u\n", (unsigned) ecode);
    	return 1;
        }

        printf("Parsing '%s' ...\n", DOCUMENT);
        if (ecode = xmlparse(ctx, DOCUMENT, (oratext *) 0,
    			XML_FLAG_VALIDATE | XML_FLAG_DISCARD_WHITESPACE))
        {
    	printf("Parse failed, error %u\n", (unsigned) ecode);
    	return 1;
        }

        puts("Outlining...");
        dump(ctx, getDocumentElement(ctx));

        xmlterm(ctx);

        return 0;
    }

    void dump(xmlctx *ctx, xmlnode *node)
    {
        const oratext *name;
        void    *nodes;
        uword    i, n_nodes;

        name = getNodeName(node);
        if (!strcmp((char *) name, "ACT"))
            dumppart(ctx, node, FALSE);
        else if (!strcmp((char *) name, "SCENE"))
            dumppart(ctx, node, TRUE);
        if (hasChildNodes(node))
        {
            nodes = getChildNodes(node);
            n_nodes = numChildNodes(nodes);
            for (i = 0; i < n_nodes; i++)
                dump(ctx, getChildNode(nodes, i));
        }
    }

    void dumppart(xmlctx *ctx, xmlnode *node, boolean indent)
    {
        void *title = getFirstChild(node);

        if (indent)
           fputs("    ", stdout);
        puts((char *) getNodeValue(getFirstChild(title)));
    }

    /* end of DOMSample.c */

### XML Parser for C Example 7: C -- DOMSample.std

The DOMSample.std example file shows the expected output from DOMSample.c

    XML C DOM sample
    Initializing XML package...
    Parsing 'cleo.xml' ...
    Outlining...
    ACT I
        SCENE I.  Alexandria. A room in CLEOPATRA's palace.
        SCENE II.  The same. Another room.
        SCENE III.  The same. Another room.
        SCENE IV.  Rome. OCTAVIUS CAESAR's house.
        SCENE V.  Alexandria. CLEOPATRA's palace.
    ACT II
        SCENE I.  Messina. POMPEY's house.
        SCENE II.  Rome. The house of LEPIDUS.
    ...
    ...
    ...
     ACT V
        SCENE I.  Alexandria. OCTAVIUS CAESAR's camp.
        SCENE II.  Alexandria. A room in the monument.

### XML Parser for C Example 8: C -- SAXSample.c

This example contains the C source code for `SAXSample.c`

    /* Copyright (c) Oracle Corporation 1999. All Rights Reserved. */

    /*
       NAME
         SAXSample.c - Sample SAX usage

       DESCRIPTION
         Sample usage of C XML parser via SAX interface
    */

    #include <stdio.h>

    #ifndef ORATYPES
    # include <oratypes.h>
    #endif

    #ifndef ORAXML_ORACLE
    # include <oraxml.h>
    #endif

    #define DOCUMENT	"cleo.xml"
    #define DEFAULT_KEYWORD	"death"

    char    *keyword;
    size_t   keylen;
    oratext *elem;
    oratext speaker[80];

    oratext *findsub(oratext *buf, size_t bufsiz, oratext *sub, size_t subsiz);
    void     savestr(oratext *buf, oratext *s, size_t len);

    /* SAX callback functions */

    sword startDocument(void *ctx);
    sword endDocument(void *ctx);
    sword startElement(void *ctx, const oratext *name,
                       const struct xmlnodes *attrs);
    sword endElement(void *ctx, const oratext *name);
    sword characters(void *ctx, const oratext *ch, size_t len);

    xmlsaxcb saxcb = {
        startDocument,
        endDocument,
        startElement,
        endElement,
        characters
    };

    int main(int argc, char **argv)
    {
        xmlctx     *ctx;
        ub4         flags;
        uword       ecode;
        flags = XML_FLAG_VALIDATE | XML_FLAG_DISCARD_WHITESPACE;

        puts("XML C SAX sample");
        keyword = (argc > 1) ? argv[1] : DEFAULT_KEYWORD;
        keylen = strlen(keyword);
        puts("Initializing XML package...");

        if (!(ctx = xmlinit(&ecode, (const oratext *) 0,
    (void (*)(void *, const oratext *, uword)) 0,
    (void *) 0, &saxcb, (void *) 0,
    (const xmlmemcb *) 0, (void *) 0,
                            (const oratext *) 0)))
        {
            (void) printf("Failed to initialize XML parser, error %u\n",
                            (unsigned) ecode);
            return 1;
        }

        printf("Parsing '%s' and looking for lines containing '%s'...\n",
    DOCUMENT, keyword);
        elem = (oratext *) "";
        if (ecode = xmlparse(ctx, (oratext *) DOCUMENT, (oratext *) 0, flags))
    return 1;

        (void) xmlterm(ctx);			/* terminate XML package */

        return 0;
    }

    sword startDocument(void *ctx)
    {
        puts("startDocument");
        return 0;
    }

    sword endDocument(void *ctx)
    {
        puts("endDocument");
        return 0;
    }

    sword startElement(void *ctx, const oratext *name,
                       const struct xmlnodes *attrs)
    {
        elem = (oratext *) name;
        return 0;
    }

    sword endElement(void *ctx, const oratext *name)
    {
        elem = (oratext *) "";
        return 0;
    }

    sword characters(void *ctx, const oratext *ch, size_t len)
    {
        if (!strcmp((char *) elem, "SPEAKER"))
    savestr(speaker, (oratext *) ch, len);
        else if (findsub((oratext *) ch, len, (oratext *) keyword, keylen))
    printf("    %s: %.*s\n", speaker, len, ch);
        return 0;
    }

    oratext *findsub(oratext *buf, size_t bufsiz, oratext *sub, size_t subsiz)
    {
        uword i;

        if (!buf || !bufsiz || (subsiz > bufsiz))
    return (oratext *) 0;
        if (!sub || !subsiz)
    return buf;
        for (i = 0; i < bufsiz - subsiz; i++, buf++)
        {
    if (!memcmp(buf, sub, subsiz))
        return buf;
        }
        return (oratext *) 0;
    }

    void savestr(oratext *buf, oratext *s, size_t len)
    {
        memcpy(buf, s, len);
        buf[len] = 0;
    }

    /* End of SAXSample.c */

### XML Parser for C Example 9: C -- SAXSample.std

`SAXSample.std` shows the expected output from `SAXSample.c`.

    XML C SAX sample
    Initializing XML package...
    Parsing 'cleo.xml' and looking for lines containing 'death'...
    startDocument
        MARK ANTONY: Who tells me true, though in his tale lie death,
        DOMITIUS ENOBARBUS: if they suffer our departure, death's the word.
        DOMITIUS ENOBARBUS: mettle in death, which commits some loving act upon
        MARK ANTONY: The death of Fulvia, with more urgent touches,
        MARK ANTONY: Is Fulvia's death.
        CLEOPATRA: In Fulvia's death, how mine received shall be.
        EROS: the poor third is up, till death enlarge his confine.
        SCARUS: Where death is sure. Yon ribaudred nag of Egypt,--
        EROS: Her head's declined, and death will seize her, but
        MARK ANTONY: I'll make death love me; for I will contend
        MARK ANTONY: Married to your good service, stay till death:
        MARK ANTONY: Than death and honour. Let's to supper, come,
        First Soldier: The hand of death hath raught him.
        CLEOPATRA: And bring me how he takes my death.
        MARK ANTONY: She hath betray'd me and shall die the death.
        MARK ANTONY: Than she which by her death our Caesar tells
        EROS: Of Antony's death.
        MARK ANTONY: A bridegroom in my death, and run into't
        DERCETAS: Thy death and fortunes bid thy followers fly.
        MARK ANTONY: Sufficing strokes for death.
        DIOMEDES: His death's upon him, but not dead.
        MARK ANTONY: I here importune death awhile, until
        CLEOPATRA: To rush into the secret house of death,
        CLEOPATRA: Ere death dare come to us? How do you, women?
        CLEOPATRA: And make death proud to take us. Come, away:
        OCTAVIUS CAESAR: And citizens to their dens: the death of Antony
        CLEOPATRA: What, of death too,
        CLEOPATRA: Where art thou, death?
        CLEOPATRA: The stroke of death is as a lover's pinch,
        CHARMIAN: Now boast thee, death, in thy possession lies
        OCTAVIUS CAESAR: Took her own way. The manner of their deaths?
    endDocument

### XML Parser for C Example 10: C -- DOMNamespace.c

This example contains the C source code for `DOMNamespace.c`.

    /* Copyright (c) Oracle Corporation 1999. All Rights Reserved. */

    /**
     ** This file demonstates a simple use of the parser and Namespace
     ** extensions to the DOM APIs.
     ** The XML file that is given to the application is parsed and the
     ** elements and attributes in the document are printed.
     **/

    #ifndef ORATYPES
    # include <oratypes.h>
    #endif

    #ifndef ORAXML_ORACLE
    # include <oraxml.h>
    #endif

    #define DOCUMENT         "NSExample.xml"

    /*------------------------------------------------------------------------
                               FUNCTION PROTOTYPES
      ------------------------------------------------------------------------*/
    static void    DOMNSprint(xmlctx *ctx);
    static void    printElements(xmlctx *ctx, xmlnode *n);
    static void    printAttrs(xmlctx *ctx, xmlnode *n);

    /*------------------------------------------------------------------------
                                    MAIN
      ------------------------------------------------------------------------*/
    int main()
    {
       xmlctx     *ctx;
       oratext    *encoding, *doc;
       void       *saxcbctx;
       const xmlsaxcb *saxcb;
       uword       ecode;
       ub4         flags;

       encoding = doc = (oratext *) 0;
       saxcbctx = (void *) 0;
       saxcb = (const xmlsaxcb *) 0;
       flags = XML_FLAG_VALIDATE | XML_FLAG_DISCARD_WHITESPACE;
       doc = (oratext *)DOCUMENT;

       /* initialize LPX context */
       if (!(ctx = xmlinit(&ecode, encoding,
                            (void (*)(void *, const oratext *, uword)) 0,
                            (void *) 0, saxcb, saxcbctx, (const xmlmemcb *) 0,
                            (void *) 0, (const oratext *) 0)))
       {
          printf("Failed to initialize XML parser, error %u\n", (unsigned) ecode);
          return -1;
       }

       /* parse the document */

       printf("\nParsing '%s' ...\n", doc);
       ecode = xmlparse(ctx, doc, encoding, flags);

       if (ecode)
         printf("Parse failed, code %u\n", (unsigned) ecode);
       else
         printf("Parse succeeded.\n");

       /* print results */

       printf("Printing results ...\n");
       DOMNSprint(ctx);

       /* terminate */

       (void) xmlterm(ctx);

       return (ecode ? -1 : 0);
    }

    /*------------------------------------------------------------------------
                                 DOMNSprint
      ------------------------------------------------------------------------*/
    static void DOMNSprint(xmlctx *ctx)
    {
        xmlnode *root;

        root = getDocumentElement(ctx);
        printf("\nThe elements are:\n");
        printElements(ctx, root);
    }

    /*------------------------------------------------------------------------
                                 printElements
      ------------------------------------------------------------------------*/
    static void printElements(xmlctx *ctx, xmlnode *n)
    {
        xmlnodes *nodes;
        uword     i;
        size_t    nn;

        const oratext   *qname;
        const oratext   *namespace;
        const oratext   *local;
        const oratext   *prefix;

        if (n == (xmlnode*)NULL)
           return;

        if (nodes = getChildNodes(n))
        {
           for (nn = numChildNodes(nodes), i = 0; i < nn; i++)
           {
              /* get node qualified name, local name, namespace, and prefix */

              qname = namespace = local = prefix = (oratext*)" ";

              if (getNodeQualifiedName(n) != (oratext*)NULL)
                 qname = getNodeQualifiedName(n);
                if (getNodePrefix(n) != (oratext*)NULL)
                 prefix = getNodePrefix(n);

              if (getNodeLocal(n) != (oratext *)NULL)
                 local = getNodeLocal(n);

              if (getNodeNamespace(n) != (oratext*)NULL)
                 namespace = getNodeNamespace(n);

              printf("  ELEMENT Qualified Name: %s\n", qname);
              printf("  ELEMENT Prefix Name   : %s\n", prefix);
              printf("  ELEMENT Local Name    : %s\n", local);
              printf("  ELEMENT Namespace     : %s\n", namespace);

              printAttrs(ctx, n);
              printElements(ctx, (xmlnode *) getChildNode(nodes, i));
           }
        }
    }

    /*------------------------------------------------------------------------
                                 printAttrs
      ------------------------------------------------------------------------*/
    static void printAttrs(xmlctx *ctx, xmlnode *n)
    {
        xmlnodes  *attrs;
        xmlnode   *a;
        uword      i;
        size_t     na;

        const oratext   *value;
        const oratext   *qname;
        const oratext   *namespace;
        const oratext   *local;
        const oratext   *prefix;

        if (attrs = getAttributes(n))
        {
           printf("\n    ATTRIBUTES: \n");
           for (na = numAttributes(attrs), i = 0; i < na; i++)
           {
              /* get attr qualified name, local name, namespace, and prefix */

              a = getAttributeIndex(attrs, i);

              qname = namespace = local = prefix = value = (oratext*)" ";

              if (getAttrQualifiedName(a) != (oratext*)NULL)
                 qname = getAttrQualifiedName(a);
              if (getAttrNamespace(a) != (oratext*)NULL)
                 namespace = getAttrNamespace(a);
              if (getAttrLocal(a) != (oratext*)NULL)
                 local = getAttrLocal(a);
              if (getAttrPrefix(a) != (oratext*)NULL)
                 prefix = getAttrPrefix(a);
              if (getAttrValue(a) != (oratext*)NULL)
                 value = getAttrValue(a);

              printf("      %s = %s\n", qname, value);
              printf("      Namespace : %s\n", namespace);
              printf("      Local Name: %s\n", local);
              printf("      Prefix    : %s\n\n", prefix);
           }
        }
        printf("\n");
    }

### XML Parser for C Example 11: C -- DOMNamespace.std

`DOMNamespace.std` shows the expected output from `DOMNamespace.c`.

    Parsing 'NSExample.xml' ...
    Parse succeeded.
    Printing results ...

    The elements are:
      ELEMENT Qualified Name: doc
      ELEMENT Prefix Name   :
      ELEMENT Local Name    : doc
      ELEMENT Namespace     : http://www.w3c.org

        ATTRIBUTES:
          nsprefix:a1 = v1
          Namespace : http://www.oracle.com
          Local Name: a1
          Prefix    : nsprefix

          xmlns = http://www.w3c.org
          Namespace :
          Local Name: xmlns
          Prefix    :

          xmlns:nsprefix = http://www.oracle.com
          Namespace :
          Local Name: nsprefix
          Prefix    : xmlns

      ELEMENT Qualified Name: child
      ELEMENT Prefix Name   :
      ELEMENT Local Name    : child
      ELEMENT Namespace     : http://www.w3c.org

### XML Parser for C Example 12: C -- SAXNamespace.c

This example contains the C source code for the `SAXNamespace.c`.

    /* Copyright (c) Oracle Corporation 1999. All Rights Reserved. */

    /**
     ** This file demonstrates a simple use of the Namespace extensions to
     ** the SAX APIs.
     **/

    #include <stdio.h>

    #ifndef ORATYPES
    # include <oratypes.h>
    #endif

    #ifndef ORAXML_ORACLE
    # include <oraxml.h>
    #endif

    #define DOCUMENT         "NSExample.xml"

    /*------------------------------------------------------------------------
                               FUNCTION PROTOTYPES
      ------------------------------------------------------------------------*/

    static int sax_startdocument(void *ctx);
    static int sax_enddocument(void *ctx);
    static int sax_endelement(void *ctx, const oratext *name);
    static int sax_nsstartelement(void *ctx, const oratext *qname,
                                   const oratext *local,
                                   const oratext *namespace,
                                   const struct xmlnodes *attrs);

    /* SAX callback structure */

    xmlsaxcb sax_callback = {
        sax_startdocument,
        sax_enddocument,
        0,
        sax_endelement,
        0,
        0,
        0,
        0,
        0,
        sax_nsstartelement,
        0, 0, 0, 0, 0, 0, 0, 0
    };

    /* SAX callback context */

    typedef struct {
        xmlctx  *ctx;
        uword    depth;
    } cbctx;

    /*------------------------------------------------------------------------
                                    MAIN
      ------------------------------------------------------------------------*/

    int main()
    {
       xmlctx     *ctx;
       uword       i;
       oratext    *doc, *encoding;
       xmlsaxcb   *saxcb;
       cbctx       saxctx;
       void       *saxcbctx;
       ub4         flags;
       uword       ecode;

       doc = encoding = (oratext *)0;
       flags = XML_FLAG_VALIDATE | XML_FLAG_DISCARD_WHITESPACE;

       doc = (oratext *)DOCUMENT;

       /* set up SAX callbacks */

       saxcb = &sax_callback;
       saxcbctx = (void *) &saxctx;

       /* initialize LPX context */
       if (!(ctx = xmlinit(&ecode, encoding,
                            (void (*)(void *, const oratext *, uword)) 0,
                            (void *) 0, saxcb, saxcbctx, (const xmlmemcb *) 0,
                            (void *) 0, (const oratext *) 0)))
       {
          printf("Failed to initialize XML parser, error %u\n", (unsigned) ecode);
          return -1;
       }

       /* parse the document */

       printf("\nParsing '%s' ...\n", doc);
       ecode = xmlparse(ctx, doc, encoding, flags);

       if (ecode)
         printf("\nParse failed, code %u\n", (unsigned) ecode);
       else
         printf("\nParse succeeded.\n");

       /* terminate */

       (void) xmlterm(ctx);

       return (ecode ? -1 : 0);
    }

    /*------------------------------------------------------------------------
                                 SAX Interface
      ------------------------------------------------------------------------*/

    static int sax_startdocument(void *ctx)
    {
        printf("\nStartDocument\n\n");
        return 0;
    }

    static int sax_enddocument(void *ctx)
    {
        printf("\nEndDocument\n");
        return 0;
    }

    static int sax_endelement(void *ctx, const oratext *name)
    {
        printf("\nELEMENT Name  : %s\n", name);
        return 0;
    }

    static int sax_nsstartelement(void *ctx, const oratext *qname,
                                   const oratext *local,
                                   const oratext *namespace,
                                   const struct xmlnodes *attrs)
    {
        cbctx   *saxctx = (cbctx *) ctx;
        xmlnode *attr;
        size_t   i;

        const oratext *aqname;
        const oratext *aprefix;
        const oratext *alocal;
        const oratext *anamespace;
        const oratext *avalue;

        /*
         * Use the functions getXXXQualifiedName(), getXXXLocalName(), and
         * getXXXNamespace() to get Namespace information.
         */

        if (qname == (oratext*)NULL)
           qname = (oratext*)" ";
        if (local == (oratext*)NULL)
           local = (oratext*)" ";
        if (namespace == (oratext*)NULL)
           namespace = (oratext*)" ";

        printf("ELEMENT Qualified Name: %s\n", qname);
        printf("ELEMENT Local Name    : %s\n", local);
        printf("ELEMENT Namespace     : %s\n", namespace);

        if (attrs)
        {
           for (i = 0; i < numAttributes(attrs); i++)
           {
              attr = getAttributeIndex(attrs, i);

              aqname = aprefix = alocal = anamespace = avalue = (oratext*)" ";

              if (getAttrQualifiedName(attr) != (oratext*)NULL)
                 aqname = getAttrQualifiedName(attr);

              if (getAttrPrefix(attr) != (oratext*)NULL)
                 aprefix = getAttrPrefix(attr);

              if (getAttrLocal(attr) != (oratext*)NULL)
                 alocal = getAttrLocal(attr);

              if (getAttrNamespace(attr) != (oratext*)NULL)
                 anamespace = getAttrNamespace(attr);

              if (getAttrValue(attr) != (oratext*)NULL)
                 avalue = getAttrValue(attr);

              printf(" ATTRIBUTE Qualified Name   : %s\n", aqname);
              printf(" ATTRIBUTE Prefix           : %s\n", aprefix);
              printf(" ATTRIBUTE Local Name       : %s\n", alocal);
              printf(" ATTRIBUTE Namespace        : %s\n", anamespace);
              printf(" ATTRIBUTE Value            : %s\n", avalue);
              printf("\n");
           }
        }
        return 0;
    }

### XML Parser for C Example 13: C -- SAXNamespace.std

`SAXNamespace.std` shows the expected output from `SAXNamespace.c`

    Parsing 'NSExample.xml' ...

    StartDocument

    ELEMENT Qualified Name: doc
    ELEMENT Local Name    : doc
    ELEMENT Namespace     : http://www.w3c.org
     ATTRIBUTE Qualified Name   : nsprefix:a1
     ATTRIBUTE Prefix           : nsprefix
     ATTRIBUTE Local Name       : a1
     ATTRIBUTE Namespace        : http://www.oracle.com
     ATTRIBUTE Value            : v1

     ATTRIBUTE Qualified Name   : xmlns
     ATTRIBUTE Prefix           :
     ATTRIBUTE Local Name       : xmlns
     ATTRIBUTE Namespace        :
     ATTRIBUTE Value            : http://www.w3c.org

     ATTRIBUTE Qualified Name   : xmlns:nsprefix
     ATTRIBUTE Prefix           : xmlns
     ATTRIBUTE Local Name       : nsprefix
     ATTRIBUTE Namespace        :
     ATTRIBUTE Value            : http://www.oracle.com

    ELEMENT Qualified Name: child
    ELEMENT Local Name    : child
    ELEMENT Namespace     : http://www.w3c.org

    ELEMENT Name  : child

    ELEMENT Name  : doc

    EndDocument

    Parse succeeded.

### XML Parser for C Example 14: C -- FullDOM.c

This example contains the C source code for `FullDOM.c`

    /* Copyright (c) Oracle Corporation 1999, 2000. All Rights Reserved. */

    /*
       NAME
         FullDOM.c

       DESCRIPTION
         Sample code to test full DOM interface
    */

    #include <stdio.h>

    #ifndef ORATYPES
    # include <oratypes.h>
    #endif

    #ifndef ORAXML_ORACLE
    # include <oraxml.h>
    #endif

    #define TEST_DOCUMENT	(oratext *) "FullDOM.xml"

    void dump(xmlnode *node, uword level);
    void dumpnode(xmlnode *node, uword level);

    static char *ntypename[] = {
        "0",
        "ELEMENT",
        "ATTRIBUTE",
        "TEXT",
        "CDATA",
        "ENTREF",
        "ENTITY",
        "PI",
        "COMMENT",
        "DOCUMENT",
        "DTD",
        "DOCFRAG",
        "NOTATION"
    };

    #define FAIL { puts("Failed!"); exit(1); }

    int main()
    {
        xmlctx     *ctx;
        xmldtd     *dtd;
        xmlnode    *doc, *elem, *node, *text, *pi, *comment, *entref,
    *subelem, *subtext, *cdata, *attr1, *attr2, *clone,
    *deep_clone, *frag, *fragelem, *fragtext, *sub2,
    *fish, *food, *gleep1, *gleep2, *repl;
        xmlnodes   *subs, *nodes, *attrs, *notes, *entities;
        uword       i, ecode, level;

        puts("XML C Full DOM test");

        puts("Initializing XML parser...");

        if (!(ctx = xmlinit(&ecode, (const oratext *) 0,
                            (void (*)(void *, const oratext *, uword)) 0,
                            (void *) 0, (const xmlsaxcb *) 0, (void *) 0,
    (const xmlmemcb *) 0, (void *) 0,
                            (const oratext *) 0)))
        {
    printf("Failed to initialze XML parser, error %u\n", (unsigned) ecode);
    return 1;
        }

        puts("\nCreating new document...");
        if (!(doc = createDocument(ctx)))
    FAIL

        puts("Document from root node:");
        dump(getDocument(ctx), 0);

        puts("\nCreating 'ROOT' element...");
        if (!(elem = createElement(ctx, (oratext *) "ROOT")))
    FAIL

        puts("Setting as 'ROOT' element...");
        if (!appendChild(ctx, doc, elem))
    FAIL

        puts("Document from 'ROOT' element:");
        dump(getDocumentElement(ctx), 0);

        puts("Adding 7 children to 'ROOT' element...");
        if (!(text = createTextNode(ctx, (oratext *) "Gibberish")) ||
            !appendChild(ctx, elem, text))
    FAIL

        if (!(comment = createComment(ctx, (oratext*) "Bit warm today, innit?")) ||
            !appendChild(ctx, elem, comment))
    FAIL

        if (!(pi = createProcessingInstruction(ctx, (oratext *) "target",
    (oratext *) "PI-contents")) ||
            !appendChild(ctx, elem, pi))
    FAIL

        if (!(cdata = createCDATASection(ctx, (oratext *) "See DATA")) ||
            !appendChild(ctx, elem, cdata))
    FAIL

        if (!(entref = createEntityReference(ctx, (oratext *) "EntRef")) ||
            !appendChild(ctx, elem, entref))
    FAIL

        if (!(fish = createElement(ctx, (oratext *) "FISH")) ||
    !appendChild(ctx, elem, fish))
    FAIL

        if (!(food = createElement(ctx, (oratext *) "FOOD")) ||
    !appendChild(ctx, elem, food))
    FAIL

        puts("Document from 'ROOT' element with its 7 children:");
        dump(getDocumentElement(ctx), 0);

        puts("\nTesting node insertion...");
        puts("Adding 'Pre-Gibberish' text node and 'Ask about the weather' comment
    node ...");
        if (!(node = createTextNode(ctx, (oratext *) "Pre-Gibberish")) ||
            !insertBefore(ctx, elem, node, text))
    FAIL

        if (!(node = createComment(ctx, (oratext *) "Ask about the weather:")) ||
            !insertBefore(ctx, elem, node, comment))
    FAIL

        puts("Document from 'ROOT' element:");
        dump(getDocumentElement(ctx), 0);

        puts("\nTesting node removal by name ...");
        puts("Removing 'FISH' element");
        if (!(nodes = getChildNodes(elem)) ||
    !removeNamedItem(nodes, (oratext *) "FISH"))
    FAIL

        puts("Document from 'ROOT' element:");
        dump(getDocumentElement(ctx), 0);

        puts("\nTesting nextSibling links starting at first child...");
        for (node = getFirstChild(elem); node; node = getNextSibling(node))
    dump(node, 1);

        puts("\nTesting previousSibling links starting at last child...");
        for (node = getLastChild(elem); node; node = getPreviousSibling(node))
    dump(node, 1);

        puts("\nTesting setting node value...");
        puts("Original node:");
        dump(pi, 1);
        setNodeValue(pi, (oratext *) "New PI contents");
        puts("Node after new value:");
        dump(pi, 1);

        puts("\nAdding another element level, i.e., 'SUB' ...");
        if (!(subelem = createElement(ctx, (oratext *) "SUB")) ||
    !insertBefore(ctx, elem, subelem, cdata) ||
    !(subtext = createTextNode(ctx, (oratext *) "Lengthy SubText")) ||
            !appendChild(ctx, subelem, subtext))
    FAIL

        puts("Document from 'ROOT' element:");
        dump(getDocumentElement(ctx), 0);

        puts("\nAdding a second 'SUB' element...");
        if (!(sub2 = createElement(ctx, (oratext *) "SUB")) ||
    !insertBefore(ctx, elem, sub2, cdata))
    FAIL

        puts("Document from 'ROOT' element:");
        dump(getDocumentElement(ctx), 0);

        puts("\nGetting all SUB nodes - note the distinct hex addresses ...");
        if (!(subs = getElementsByTagName(ctx, (xmlnode *) 0, (oratext *) "SUB")))
    FAIL
        for (i = 0; i < getNodeMapLength(subs); i++)
    dumpnode(getChildNode(subs, i), 1);

        puts("\nTesting parent links...");
        for (level = 1, node = subtext; node; node = getParentNode(node), level++)
    dumpnode(node, level);

        puts("\nTesting owner document of node...");
        dumpnode(subtext, 1);
        dumpnode(getOwnerDocument(subtext), 1);

        puts("\nTesting node replacement...");
        if (!(node = createTextNode(ctx, (oratext *) "REPLACEMENT, 1/2 PRICE")) ||
            !replaceChild(ctx, pi, node))
    FAIL

        puts("Document from 'ROOT' element:");
        dump(getDocumentElement(ctx), 0);

        puts("\nTesting node removal...");
        if (!removeChild(entref))
    FAIL

        puts("Document from 'ROOT' element:");
        dump(getDocumentElement(ctx), 0);

        puts("\nNormalizing...");
        normalize(ctx, elem);

        puts("Document from 'ROOT' element:");
        dump(getDocumentElement(ctx), 0);

        puts("\nCreating and populating document fragment...");
        if (!(frag = createDocumentFragment(ctx)) ||
    !(fragelem = createElement(ctx, (oratext *) "FragElem")) ||
    !(fragtext = createTextNode(ctx, (oratext *) "FragText")) ||
    !appendChild(ctx, frag, fragelem) ||
    !appendChild(ctx, frag, fragtext))
    FAIL
        dump(frag, 1);

        puts("Insert document fragment...");
        if (!insertBefore(ctx, elem, frag, comment))
    FAIL
        dump(elem, 1);

        puts("\nCreate two attributes...");
        if (!(attr1 = createAttribute(ctx,(oratext*)"Attr1",(oratext*)"Value1")) ||
    !(attr2 = createAttribute(ctx,(oratext*)"Attr2",(oratext*)"Value2")))
    FAIL
        puts("Setting attributes...");
        if (!setAttributeNode(ctx, subelem, attr1, NULL) ||
    !setAttributeNode(ctx, subelem, attr2, NULL))
    FAIL
        dump(subelem, 1);

        puts("\nAltering attribute1 value...");
        setAttrValue(attr1, (oratext *) "New1");
        dump(subelem, 1);

        puts("\nFetching attribute by name (Attr2)...");
        if (!(node = getAttributeNode(subelem, (oratext *) "Attr2")))
    FAIL
        dump(node, 1);

        puts("\nRemoving attribute by name (Attr1)...");
        removeAttribute(subelem, (oratext *) "Attr1");
        dump(subelem, 1);

        puts("\nAdding new attribute...");
        if (!setAttribute(ctx, subelem, (oratext *) "Attr3", (oratext *) "Value3"))
    FAIL
        dump(subelem, 1);

        puts("\nRemoving attribute by pointer (Attr2)...");
        if (!removeAttributeNode(subelem, attr2))
    FAIL
        dump(subelem, 1);

        puts("\nAdding new attribute w/same name (test replacement)...");
        dump(subelem, 1);
        if (!(node = createAttribute(ctx, (oratext*)"Attr3", (oratext*)"Zoo3")))
    FAIL
        if (!setAttributeNode(ctx, subelem, node, NULL))
    FAIL
        dump(subelem, 1);

        puts("\nTesting node (attr) set by name ...");
        puts("Adding 'GLEEP' attribute and printing out hex addresses of node set");
        attrs = getAttributes(subelem);
        if (!(gleep1=createAttribute(ctx,(oratext*)"GLEEP",(oratext*)"gleep1")) ||
    !setNamedItem(ctx, attrs, gleep1, NULL))
    FAIL
        dump(subelem, 1);

        puts("\nTesting node set by name ...");
        puts("Replacing 'GLEEP' attribute - note the changed hex address");
        if (!(gleep2=createAttribute(ctx,(oratext*)"GLEEP",(oratext*)"gleep2")) ||
    !setNamedItem(ctx, attrs, gleep2, &repl))
    FAIL
        dump(subelem, 1);
        puts("Replaced node was:");
        dump(repl, 1);

        puts("\nOriginal SubROOT...");
        dump(subelem, 1);
        puts("Cloned SubROOT (not deep)...");
        clone = cloneNode(ctx, subelem, FALSE);
        dump(clone, 1);
        puts("Cloned SubROOT (deep)...");
        deep_clone = cloneNode(ctx, subelem, TRUE);
        dump(deep_clone, 1);

        puts("\nSplitting text...");
        dump(subelem, 1);
        splitText(ctx, subtext, 3);
        dump(subelem, 1);

        puts("\nTesting string operations...");
        printf("    CharData = \"%s\"\n", getCharData(subtext));
        puts("Setting new data...");
        setCharData(subtext, (oratext *) "0123456789");
        printf("    CharData = \"%s\"\n", getCharData(subtext));
        printf("    CharLength = %d\n", getCharLength(subtext));
        printf("    Substring(0,5) = \"%s\"\n",
    substringData(ctx, subtext, 0, 5));
        printf("    Substring(8,2) = \"%s\"\n",
    substringData(ctx, subtext, 8, 2));
        puts("Appending data...");
        appendData(ctx, subtext, (oratext *) "ABCDEF");
        printf("    CharData = \"%s\"\n", getCharData(subtext));
        puts("Inserting data...");
        insertData(ctx, subtext, 10, (oratext *) "*foo*");
        printf("    CharData = \"%s\"\n", getCharData(subtext));
        puts("Deleting data...");
        deleteData(ctx, subtext, 0, 10);
        printf("    CharData = \"%s\"\n", getCharData(subtext));
        puts("Replacing data...");
        replaceData(ctx, subtext, 1, 3, (oratext *) "bamboozle");
        printf("    CharData = \"%s\"\n", getCharData(subtext));

        puts("Cleaning up...");
        xmlclean(ctx);

        if (getDocument(ctx))
        {
    puts("Problem, document is not gone!!");
    return 1;
        }

        puts("Parsing test document...");
        if (ecode = xmlparse(ctx, TEST_DOCUMENT, (oratext *) 0, 0))
        {
    printf("Parse failed, code %d\n", (int) ecode);
    return 1;
        }

        puts("Document from root node:");
        dump(getDocument(ctx), 0);

        dtd = getDocType(ctx);

        puts("Testing getDocTypeNotations...");
        if (notes = getDocTypeNotations(dtd))
        {
    size_t n_notes = numChildNodes(notes);

    printf("# of notations = %d\n", (int) n_notes);
    for (i = 0; i < n_notes; i++)
        dump(getChildNode(notes, i), 1);
        }
        else
    puts("No defined notations\n");

        puts("Testing getDocTypeEntities...");
        if (entities = getDocTypeEntities(dtd))
        {
    size_t n_entities = numChildNodes(entities);

    printf("# of entities = %d\n", (int) n_entities);
    for (i = 0; i < n_entities; i++)
    	    dump(getChildNode(entities, i), 1);
        }
        else
    puts("No defined entities\n");

        puts("Cleaning up...");
        xmlclean(ctx);

        if (getDocument(ctx))
        {
    puts("Problem, document is not gone!!\n");
    return 1;
        }

        puts("\nTerminating parser...");
        xmlterm(ctx);

        puts("Success.");
        return 0;
    }

    void dump(xmlnode *node, uword level)
    {
        xmlnodes *nodes;
        uword     i, n_nodes;

        if (node)
        {
    dumpnode(node, level);
    if (hasChildNodes(node))
    {
        nodes = getChildNodes(node);
        n_nodes = numChildNodes(nodes);
        for (i = 0; i < n_nodes; i++)
    dump(getChildNode(nodes, i), level + 1);
    }
       }

    void dumpnode(xmlnode *node, uword level)
    {
        const oratext  *name, *value;
        xmlntype  type;
        xmlnodes *attrs;
        xmlnode  *attr;
        uword     i, n_attrs;

        if (node)
        {
    for (i = 0; i <= level; i++)
        fputs("    ", stdout);
    type = getNodeType(node);
    fputs(ntypename[type], stdout);
    if ((name = getNodeName(node)) && (*name != '#'))
        printf(" \"%s\"", (char *) name);
    if (value = getNodeValue(node))
        printf(" = \"%s\"", (char *) value);
    if ((type == ELEMENT_NODE) && (attrs = getAttributes(node)))
    {
        fputs(" [", stdout);
        n_attrs = numAttributes(attrs);
        for (i = 0; i < n_attrs; i++)
        {
    if (i) fputs(", ", stdout);
    attr = getAttributeIndex(attrs, i);
    fputs((char *) getAttrName(attr), stdout);
    if (getAttrSpecified(attr))
        putchar('*');
    printf("=\"%s\"", (char *) getAttrValue(attr));
        }
        putchar(']');
    }
    putchar('\n');
        }
    }

    /* end of FullDOM.c */

### XML Parser for C Example 15: C -- FullDOM.std

`FullDOM.std` shows the expected output from `FullDOM.c`.

    XML C Full DOM test
    Initializing XML parser...

    Creating new document...
    Document from root node:
        DOCUMENT

    Creating 'ROOT' element...
    Setting as 'ROOT' element...
    Document from 'ROOT' element:
        ELEMENT "ROOT"
    Adding 7 children to 'ROOT' element...
    Document from 'ROOT' element with its 7 children:
        ELEMENT "ROOT"
            TEXT = "Gibberish"
            COMMENT = "Bit warm today, innit?"
            PI "target" = "PI-contents"
            CDATA = "See DATA"
            ENTREF "EntRef"
            ELEMENT "FISH"
            ELEMENT "FOOD"

    Testing node insertion...
    Adding 'Pre-Gibberish' text node and 'Ask about the weather' comment node ...
    Document from 'ROOT' element:
        ELEMENT "ROOT"
            TEXT = "Pre-Gibberish"
            TEXT = "Gibberish"
            COMMENT = "Ask about the weather:"
            COMMENT = "Bit warm today, innit?"
            PI "target" = "PI-contents"
            CDATA = "See DATA"
            ENTREF "EntRef"
            ELEMENT "FISH"
            ELEMENT "FOOD"

    Testing node removal by name ...
    Removing 'FISH' element
    Document from 'ROOT' element:
        ELEMENT "ROOT"
            TEXT = "Pre-Gibberish"
            TEXT = "Gibberish"
            COMMENT = "Ask about the weather:"
            COMMENT = "Bit warm today, innit?"
            PI "target" = "PI-contents"
            CDATA = "See DATA"
            ENTREF "EntRef"
            ELEMENT "FOOD"

    Testing nextSibling links starting at first child...
            TEXT = "Pre-Gibberish"
            TEXT = "Gibberish"
            COMMENT = "Ask about the weather:"
            COMMENT = "Bit warm today, innit?"
            PI "target" = "PI-contents"
            CDATA = "See DATA"
            ENTREF "EntRef"
            ELEMENT "FOOD"

    Testing previousSibling links starting at last child...
            ELEMENT "FOOD"
            ENTREF "EntRef"
            CDATA = "See DATA"
            PI "target" = "PI-contents"
            COMMENT = "Bit warm today, innit?"
            COMMENT = "Ask about the weather:"
            TEXT = "Gibberish"
            TEXT = "Pre-Gibberish"

    Testing setting node value...
    Original node:
            PI "target" = "PI-contents"
    Node after new value:
            PI "target" = "New PI contents"

    Adding another element level, i.e., 'SUB' ...
    Document from 'ROOT' element:
        ELEMENT "ROOT"
            TEXT = "Pre-Gibberish"
            TEXT = "Gibberish"
            COMMENT = "Ask about the weather:"
            COMMENT = "Bit warm today, innit?"
            PI "target" = "New PI contents"
            ELEMENT "SUB"
                TEXT = "Lengthy SubText"
            CDATA = "See DATA"
            ENTREF "EntRef"
            ELEMENT "FOOD"

    Adding a second 'SUB' element...
    Document from 'ROOT' element:
        ELEMENT "ROOT"
            TEXT = "Pre-Gibberish"
            TEXT = "Gibberish"
            COMMENT = "Ask about the weather:"
            COMMENT = "Bit warm today, innit?"
            PI "target" = "New PI contents"
            ELEMENT "SUB"
                TEXT = "Lengthy SubText"
            ELEMENT "SUB"
            CDATA = "See DATA"
            ENTREF "EntRef"
            ELEMENT "FOOD"

    Getting all SUB nodes - note the distinct hex addresses ...
            ELEMENT "SUB"
            ELEMENT "SUB"

    Testing parent links...
            TEXT = "Lengthy SubText"
                ELEMENT "SUB"
                    ELEMENT "ROOT"
                        DOCUMENT

    Testing owner document of node...
            TEXT = "Lengthy SubText"
            DOCUMENT

    Testing node replacement...
    Document from 'ROOT' element:
        ELEMENT "ROOT"
            TEXT = "Pre-Gibberish"
            TEXT = "Gibberish"
            COMMENT = "Ask about the weather:"
            COMMENT = "Bit warm today, innit?"
            TEXT = "REPLACEMENT, 1/2 PRICE"
            ELEMENT "SUB"
                TEXT = "Lengthy SubText"
            ELEMENT "SUB"
            CDATA = "See DATA"
            ENTREF "EntRef"
            ELEMENT "FOOD"

    Testing node removal...
    Document from 'ROOT' element:
        ELEMENT "ROOT"
            TEXT = "Pre-Gibberish"
            TEXT = "Gibberish"
            COMMENT = "Ask about the weather:"
            COMMENT = "Bit warm today, innit?"
            TEXT = "REPLACEMENT, 1/2 PRICE"
            ELEMENT "SUB"
                TEXT = "Lengthy SubText"
            ELEMENT "SUB"
            CDATA = "See DATA"
            ELEMENT "FOOD"

    Normalizing...
    Document from 'ROOT' element:
        ELEMENT "ROOT"
            TEXT = "Pre-GibberishGibberish"
            COMMENT = "Ask about the weather:"
            COMMENT = "Bit warm today, innit?"
            TEXT = "REPLACEMENT, 1/2 PRICE"
            ELEMENT "SUB"
                TEXT = "Lengthy SubText"
            ELEMENT "SUB"
            CDATA = "See DATA"
            ELEMENT "FOOD"

    Creating and populating document fragment...
            DOCFRAG
                ELEMENT "FragElem"
                TEXT = "FragText"
    Insert document fragment...
            ELEMENT "ROOT"
                TEXT = "Pre-GibberishGibberish"
                COMMENT = "Ask about the weather:"
                ELEMENT "FragElem"
                TEXT = "FragText"
                COMMENT = "Bit warm today, innit?"
                TEXT = "REPLACEMENT, 1/2 PRICE"
                ELEMENT "SUB"
                    TEXT = "Lengthy SubText"
                ELEMENT "SUB"
                CDATA = "See DATA"
                ELEMENT "FOOD"

    Create two attributes...
    Setting attributes...
            ELEMENT "SUB" [Attr1*="Value1", Attr2*="Value2"]
                TEXT = "Lengthy SubText"

    Altering attribute1 value...
            ELEMENT "SUB" [Attr1*="New1", Attr2*="Value2"]
                TEXT = "Lengthy SubText"

    Fetching attribute by name (Attr2)...
            ATTRIBUTE "Attr2" = "Value2"

    Removing attribute by name (Attr1)...
            ELEMENT "SUB" [Attr2*="Value2"]
                TEXT = "Lengthy SubText"

    Adding new attribute...
            ELEMENT "SUB" [Attr2*="Value2", Attr3*="Value3"]
                TEXT = "Lengthy SubText"

    Removing attribute by pointer (Attr2)...
            ELEMENT "SUB" [Attr3*="Value3"]
                TEXT = "Lengthy SubText"

    Adding new attribute w/same name (test replacement)...
            ELEMENT "SUB" [Attr3*="Value3"]
                TEXT = "Lengthy SubText"
            ELEMENT "SUB" [Attr3*="Zoo3"]
                TEXT = "Lengthy SubText"

    Testing node (attr) set by name ...
    Adding 'GLEEP' attribute and printing out hex addresses of node set
            ELEMENT "SUB" [Attr3*="Zoo3", GLEEP*="gleep1"]
                TEXT = "Lengthy SubText"

    Testing node set by name ...
    Replacing 'GLEEP' attribute - note the changed hex address
            ELEMENT "SUB" [Attr3*="Zoo3", GLEEP*="gleep2"]
                TEXT = "Lengthy SubText"
    Replaced node was:
            ATTRIBUTE "GLEEP" = "gleep1"

    Original SubROOT...
            ELEMENT "SUB" [Attr3*="Zoo3", GLEEP*="gleep2"]
                TEXT = "Lengthy SubText"
    Cloned SubROOT (not deep)...
            ELEMENT "SUB" [Attr3*="Zoo3", GLEEP*="gleep2"]
                TEXT = "Lengthy SubText"
    Cloned SubROOT (deep)...
            ELEMENT "SUB" [Attr3*="Zoo3", GLEEP*="gleep2"]
                TEXT = "Lengthy SubText"

    Splitting text...
            ELEMENT "SUB" [Attr3*="Zoo3", GLEEP*="gleep2"]
                TEXT = "Lengthy SubText"
            ELEMENT "SUB" [Attr3*="Zoo3", GLEEP*="gleep2"]
                TEXT = "Leng"
                TEXT = "thy SubText"

    Testing string operations...
        CharData = "Leng"
    Setting new data...
        CharData = "0123456789"
        CharLength = 10
        Substring(0,5) = "01234"
        Substring(8,2) = "89"
    Appending data...
        CharData = "0123456789ABCDEF"
    Inserting data...
        CharData = "0123456789*foo*ABCDEF"
    Deleting data...
        CharData = "*foo*ABCDEF"
    Replacing data...
        CharData = "*bamboozle*ABCDEF"
    Cleaning up...
    Parsing test document...
    Document from root node:
        DOCUMENT
            DTD "doc"
            ELEMENT "doc" [xml:lang*="foo"]
                ELEMENT "p" [xml:space="preserve"]
                    TEXT = "An ampersand (&) may be escaped
    numerically (&#38;) or with a general entity
    (&amp;)."
    Testing getDocTypeNotations...
    # of notations = 2
            NOTATION "notation1"
            NOTATION "notation2"
    Testing getDocTypeEntities...
    # of entities = 1
            ENTITY "example" = "<p>An ampersand (&#38;) may be escaped
    numerically (&#38;#38;) or with a general entity
    (&amp;amp;).</p>"
    Cleaning up...

    Terminating parser...
    Success.

### XML Parser for C Example 16: C -- XSLSample.c

This example contains C source code for `XSLSample.c.`

    /* Copyright (c) Oracle Corporation 1999. All Rights Reserved. */

    /*
       NAME
         XSLSample.c - Sample function for XSL
       DESCRIPTION
         Sample usage of C XSL Processor
    */

    #include <stdio.h>
    #ifndef ORATYPES
    # include <oratypes.h>
    #endif

    #ifndef ORAXML_ORACLE
    # include <oraxml.h>
    #endif

    int main(int argc, char *argv[])
    {
        xmlctx     *xctx, *xslctx, *resctx;
        xmlnode    *result;
        uword       ecode;
        /* Check for correct usage */
        if (argc < 3)
            {
            puts("Usage is XSLSample <xmlfile> <xslfile>\n");
            return 1;
            }

        /* Parse the XML document */
        if (!(xctx = xmlinit(&ecode, (const oratext *) 0,
                            (void (*)(void *, const oratext *, uword)) 0,
                            (void *) 0, (const xmlsaxcb *) 0, (void *) 0,
                            (const xmlmemcb *) 0, (void *) 0,
                            (const oratext *) 0)))
        {
            printf("Failed to initialze XML parser, error %u\n", (unsigned) ecode);
            return 1;
        }

        printf("Parsing '%s' ...\n", argv[1]);
        if (ecode = xmlparse(xctx, (oratext *)argv[1], (oratext *) 0,
                            XML_FLAG_VALIDATE | XML_FLAG_DISCARD_WHITESPACE))
        {
            printf("Parse failed, error %u\n", (unsigned) ecode);
            return 1;
        }

        /* Parse the XSL document */
        if (!(xslctx = xmlinit(&ecode, (const oratext *) 0,
                            (void (*)(void *, const oratext *, uword)) 0,
                            (void *) 0, (const xmlsaxcb *) 0, (void *) 0,
                            (const xmlmemcb *) 0, (void *) 0,
                            (const oratext *) 0)))
        {
            printf("Failed to initialze XML parser, error %u\n", (unsigned) ecode);
            return 1;
        }

        printf("Parsing '%s' ...\n", argv[2]);
        if (ecode = xmlparse(xslctx, (oratext *)argv[2], (oratext *) 0,
                            XML_FLAG_VALIDATE | XML_FLAG_DISCARD_WHITESPACE))
        {
            printf("Parse failed, error %u\n", (unsigned) ecode);
            return 1;
        }

        /* Initialize the result context */
        if (!(resctx = xmlinit(&ecode, (const oratext *) 0,
                            (void (*)(void *, const oratext *, uword)) 0,
                            (void *) 0, (const xmlsaxcb *) 0, (void *) 0,
                            (const xmlmemcb *) 0, (void *) 0,
                            (const oratext *) 0)))
        {
            printf("Failed to initialze XML parser, error %u\n", (unsigned) ecode);
            return 1;
        }

        /* XSL processing */
        printf("XSL Processing\n");
        if (ecode = xslprocess(xctx, xslctx, resctx, &result))
        {
            printf("Parse failed, error %u\n", (unsigned) ecode);
            return 1;
        }

        /* Print the result tree */
        printres(resctx, result);

        /* Call the terminate functions */
        (void)xmlterm(xctx);
        (void)xmlterm(xslctx);
        (void)xmlterm(resctx);

        return 0;
    }

### XML Parser for C Example 17: C -- XSLSample.std

`XSLSample.std` shows the expected output from `XSLSample.c`.

    Parsing 'class.xml' ...
    Parsing 'iden.xsl' ...
    XSL Processing
    <root>
       <course>
          <Name>Calculus</Name>
          <Dept>Math</Dept>
          <Instructor>
             <Name>Jim Green</Name>
          </Instructor>
          <Student>
             <Name>Jack</Name>
             <Name>Mary</Name>
             <Name>Paul</Name>
          </Student>
       </course>
    </root>

| Copyright © 2001, 2003 Oracle Corporation. All Rights Reserved. |
Home | Contents | Index