This chapter contains these topics:
Note:
Use the new unified C API for new XDK and Oracle XML DB applications. The old C functions are deprecated and supported only for backward compatibility, but will not be enhanced. They will be removed in a future release.The new C API is described in "Overview of the Unified C API".
The XML Schema processor for C is a companion component to the XML parser for C that allows support for simple and complex datatypes in XML applications.
The XML Schema processor for C supports the W3C XML Schema Recommendation. This makes writing custom applications that process XML documents straightforward, and means that a standards-compliant XML Schema processor is part of the XDK on every operating system where Oracle is ported.
The XML Schema processor enables validation of XML and retrieval of metadata. It can be called by itself or through the XML Parser for C.
See Also:
Chapter 4, "XML Parsing for Java", for more information about XML Schema and why you would want to use XML Schema.XML Schema processor for C has the following features:
Supports simple and complex types
Built on XML parser for C
Supports the W3C XML Schema Recommendation
See Also:
Oracle Database XML C API Reference "Schema APIs for C"
$ORACLE_HOME/xdk/demo/c/schema/
- sample code
The Schema Processor conforms to the following standards:
W3C recommendation for Extensible Markup Language (XML) 1.0
W3C recommendation for Document Object Model Level 1.0
W3C recommendation for Namespaces in XML
W3C recommendation for XML Schema
Table 20-1 lists the supplied files and directories for this release.
Table 20-1 XML Schema Processor for C: Supplied Files in $ORACLE_HOME
Directory and Files | Description |
---|---|
|
schema processor executable, |
|
XML/XSL/Schema & support libraries |
|
Globalization Support data files |
|
example usage of the Schema processor |
|
header files |
|
error message files |
|
introductory file |
Table 20-2 lists the included libraries in directory lib
.
XML Schema processor for C can be called as an executable by invoking bin/schema
in the install area. This takes two arguments:
XML instance document
Optionally, a default schema
The XML Schema processor for C can also be invoked by writing code using the supplied APIs. The code must be compiled using the headers in the include
subdirectory and linked against the libraries in the lib
subdirectory. See Makefile
in the xdk/demo/c/schema
subdirectory for details on how to build your program.
Error message files in different languages are provided in the mesg/
subdirectory.
Figure 20-1 describes the calling sequence for the XML Schema processor for C, as follows:
The initialize call is invoked once at the beginning of a session; it returns a schema context which is used throughout the session.
Schema documents to be used in the session are loaded in advance.
The instance document to be validated is first parsed with the XML parser.
The top of the XML element subtree for the instance is then passed to the schema validate function.
If no explicit schema is defined in the instance document, any pre-loaded schemas will be used.
More documents can then be validated using the same schema context.
When the session is over, the Schema tear-down function is called, which releases all memory allocated for the loaded schemas.
Figure 20-1 XML Schema Processor for C Usage Diagram
The directory xdk/demo/c/schema
contains sample XML Schema applications that illustrate how to use Oracle XML Schema processor with its API. Table 20-3 lists the provided sample files.
Table 20-3 XML Schema for C Samples Provided
Sample File | Description |
---|---|
|
Makefile to build the sample programs and run them, verifying correct output. |
|
Program which invokes the XML Schema for C API |
|
Sample schema, instance document, and expected output respectively, after running |
|
Second sample schema, instance document, and expected output respectively, after running |
|
Third sample schema, instance document, and expected output respectively, after running |
To build the sample programs, run make
.
To build the programs and run them, comparing the actual output to expected output:
make sure
The streaming validator was introduced in Oracle Database 11g Release 1 (11.1). It uses XML Events, which is a representation of an XML document that is similar to SAX Events. XML events has a start tag, end tag, and comment. The producer drives the SAX events and the consumer drives the XML events. The streaming validator shares software with the older schema validator and derives most functionality from it. Memory overhead is less than for the DOM representation used in the older validator. Only one pass is made over the document.
There are two modes of streaming validation:
Transparent mode - events are returned to the application.
Opaque mode - events are not returned to the application but an error indicating success or failure of the document validation process is returned.
Before document validation, the regular validation context must be created, and the relevant schema must be loaded using this context. Then XML event context for pull parser (or for another event producer) must be created. This event context is then given to the streaming validator, so that it is able to request events from the producer.
Passing in a schema DOM to the XmlSchemaLoad
API is also supported.
An application starts with a call to XmlEvCreateSVCtx(
). This call creates and returns an event context of type xmlctx
, which must be passed on all subsequent calls to the streaming validator. The event context created must be terminated by a call to XmlEvDestroyCtx()
.
After creation of the event context, the application repeatedly advances validation to the next event by issuing calls to XmlEvNext()
, which returns the type of the next event. Additional API interfaces allow the application to retrieve information relevant to the last event.
There is no notion of a valid event. Validity is the property of a document and not of the individual items and events of the document. The errors are:
XML_EVENT_FATAL_ERROR
- When the producer of XML events reports this error, the streaming validator returns this event back to the application and stops the validation process.
XML_EVENT_ERROR
- The streaming validator returns this event to the application when a validation error occurs. The application can then call XmlEvGetError()
to get more information about the error.
If the application does not receive any XML_EVENT_ERROR
or XML_EVENT_FATAL_ERROR
events, the document is valid. Therefore, the application must handle these events and not ignore them.
These errors are not cached and the associated information is not available for later retrieval.
Here is an example in transparent mode:
Example 20-1 Streaming Validator in Transparent Mode
# include "xmlev.h" ... xmlevctx *ppevtcx, *svevctx; xmlctx *xctx xsdctx *sctx; if (!(xctx = XmlCreate(&xerr, (oratext *) "test"))) printf("Failed to create XML context, error %u\n", (unsigned) xerr); ... if (!(sctx = XmlSchemaCreate(xctx, &xerr, NULL))) printf("Failed to create schema context, error %u\n", (unsigned) xerr); ... If (xerr = XmlSchemaLoad(sctx, "my_schema.xsd", NULL)) printf("Failed to load schema, error %u\n", (unsigned) xerr); if(!(ppevctx = XmlEvCreatePPCtx(xctx, &xerr, NULL))) printf("Failed to create EVENT context, error %u\n", (unsigned) xerr); if(xerr = XmlEvLoadPPDoc(xctx, ppevctx, "file", "test.xml", 0, NULL)) printf("Failed to load Document, error %u\n", (unsigned) xerr); ... If(!(svevctx = XmlEvCreateSVCtx(xctx, sctx, ppevctx, &xerr))) printf("Failed to create SVcontext, error %u\n", (unsigned) xerr); ... for(;;) { xmlevtype cur_event; cur_event = XmlEvNext(svevctx); switch(cur_event) { case XML_EVENT_FATAL_ERROR: printf("FATAL ERROR"); /* error processing goes here */ return; case XML_EVENT_ERROR: XmlEvGetError(svevctx, oratext *msg); printf("Validation Failed, Error %s\n", msg); break; case XML_EVENT_START_ELEMENT: printf("<%s>", XmlEvGetName(svevctx)); break; ... case XML_EVENT_END_DOCUMENT: printf("END DOCUMENT"); return; } } ... XmlEvDestroySVCtx(svevctx); XmlSchemaDestroy(sctx); XmlEvDestroyCtx(ppevctx); XmlDestroyCtx(xctx);
In opaque mode, the streaming validator reads the instance document to be validated as a sequence of events from the producer, but does not pass the events to the application (consumer). It returns XMLERR_OK
on success and an error number on failure.
After the schema has been loaded and the XML Events context has been initialized, the application can validate the document in this mode with a call to XmlEvSchemaValidate()
. The signature of this function will take a pointer to the events context. The declaration is as follows:
xmlerr XmlEvSchemaValidate(xmlctx *xctx, xsdctx *sctx, xmlevctx *evctx, oratext **errmsg); /* Returns (xmlerr), the error code */
When the streaming validator encounters an error, XmlEvSchemaValidate()
returns an error number. This could be because of a parse error or a validation error. The application can then use the existing XmlEvGetError
APIs to get the error message. The error message is parameterized and typically has all the errors leading up to the point where the streaming validator terminated.
Here is an example in opaque mode:
Example 20-2 Example of Streaming Validator in Opaque Mode
# include "xmlev.h" ... xmlevctx *ppevtcx; xmlctx *xctx; xsdctx *sctx; oratext **errmsg; xmlerr xerr; if (!(xctx = XmlCreate(&xerr, (oratext *) "test")) printf("Failed to create XML context, error %u\n", (unsigned) xerr); ... if (!(sctx = XmlSchemaCreate(xctx, &xerr, NULL))) printf("Failed to create schema context, error %u\n", (unsigned) xerr); ... if (xerr = XmlSchemaLoad(sctx, "my_schema.xsd", NULL)) printf("Failed to load schema, error %u\n", (unsigned) xerr); if(!(ppevctx = XmlEvCreatePPCtx(xctx, &xerr, NULL))) printf("Failed to create EVENT context, error %u\n", (unsigned) xerr); if(xerr = XmlEvLoadPPDoc(xctx, ppevctx, "file", "test.xml", 0, NULL)) printf("Failed to load Document, error %u\n", (unsigned) xerr); if((xerr = XmlEvSchemaValidate(xctx, sctx, ppevctx, errmsg))) { printf("Validation Failed, Error: %s\n", errmsg); } ... XmlSchemaDestroy(sctx); XmlEvDestroyCtx(ppevctx); XmlDestroyCtx(xctx);
XmlSchemaLoad()
was enhanced in Oracle Database 11g Release 1 (11.1) to work with an existing DOM. Previously, this function took two fixed arguments and a set of variable properties. The first argument is the schema context; the second is the URL location of the schema document. A new property was added to the set of variable arguments to provide access to the schema DOM given a URL. The property schema_dom_callback
is a callback function provided by the application. If supplied, the schema load function will use this callback to access the DOM for the main schema as well as any included, imported, or redefined schemas. The callback signature is as follows:
typedef xmldocnode* (*xmlsch_dom_callback) (xmlctx *xctx, oratext *uri, xmlerr *xerr);
This callback accepts a URI (the schema load function will pass in the URI of the document desired) and returns the document node. An example follows:
Example 20-3 XmlSchemaLoad() Example
# include "xmlev.h" ... xmlctx *xctx; xsdctx *sctx; xmldocnode *doc; if (!(xctx = XmlCreate(&xerr, (oratext *) "test")) printf("Failed to create XML context, error %u\n", (unsigned) xerr); ... if (!(sctx = XmlSchemaCreate(xctx, &xerr, NULL))) printf("Failed to create schema context, error %u\n", (unsigned) xerr); ... If (xerr = XmlSchemaLoad(sctx, schema_uri, "schema_dom_callback", func1, NULL)) printf("Failed to load schema, error %u\n", (unsigned) xerr); ... XmlSchemaDestroy(sctx); XmlDestroyCtx(xctx);
You can supply options to the validation process using XmlSchemaSetValidateOptions()
. For example:
XmlSchemaSetValidateOptions(scctx, "ignore_id_constraint", (boolean)TRUE, NULL);
The options are:
ignore_id_constraint
(existing before Oracle Database 11g Release 1 (11.1))
ignore_sch_location
(existing before Oracle Database 11g Release 1 (11.1))
ignore_par_val_rest
(existing before Oracle Database 11g Release 1 (11.1))
ignore_pattern_check
: When this property is TRUE
, the streaming validator ignores pattern-facet checks. The default is FALSE
.
no_events_for_defaults
: When this property is TRUE
, the streaming validator will not return events for default values added to the instance document. This option can be used in the transparent case only.
Example 20-4 Example of Streaming Validator Using New Options
# include "xmlev.h" ... xmlevctx *ppevtcx; xmlctx *xctx; xsdctx *sctx; xmlerr xerr; oratext **errmsg; if (!(xctx = XmlCreate(&xerr, (oratext *) "test")) printf("Failed to create XML context, error %u\n", (unsigned) xerr); ... if (!(sctx = XmlSchemaCreate(xctx, &xerr, NULL))) printf("Failed to create schema context, error %u\n", (unsigned) xerr); ... If (xerr = XmlSchemaLoad(sctx, "my_schema.xsd", NULL)) printf("Failed to load schema, error %u\n", (unsigned) xerr); if(!(ppevctx = XmlEvCreatePPCtx(xctx, &xerr, "file", "test.xml", NULL))) printf("Failed to create EVENT context, error %u\n", (unsigned) xerr); if(xerr = XmlEvLoadPPDoc(xctx, ppevctx, "file", "test.xml", 0, NULL)) printf("Failed to load Document, error %u\n", (unsigned) xerr); XmlSchemaSetValidateOptions(sctx, "ignore_id_constraint", TRUE, "ignore_pattern_facet", TRUE, NULL); if((xerr = XmlEvSchemaValidate(xctx,sctx, ppevctx, errmsg))) { printf("Validation Failed, Error: %s\n", errmsg); } ... XmlSchemaDestroy(sctx); XmlEvDestroyCtx(ppevctx); XmlDestroyCtx(xctx);