Plsqlap_Document_API Overview

The package Plsqlap_Document_API is meant as a replacement for the deprecated package Plsqlap_Record_API. A PL/SQL AP Document is a dynamic data structure that corresponds to a document modeled in a serverpackage model in Developer Studio. A document consist of simple and compound attributes. A simple attribute (or just an attribute) is of a given type and contains a value. A compound attribute (an aggregate) can contain just a single document or a collection of documents (an array).

Some operations modeled in Developer Studio take array of documents as argument rather then a single document. PL/SQL AP Document allows also creation of an array of documents.

Contents

Document handling

Developer Studio generates Meta data for each modeled document. This Meta data is available in the middle tire (in Java), but not in the database layer. Therefore this is developers responsibility to handle proper document structure. Any discrepancy from the Meta data definition will result in runtime errors.

In communication between layers documents are serialized to and from IFS XML. IFS XML is just a subset of XML. The framework will normally serialize attribute names to upper case XML tag names with underscores, but it is possible to override default behavior using properties in Developer Studio. Therefore all names in PL/SQL AP Document are case sensitive.

A PL/SQL AP Document is implemented as an in-memory collection of elements, so for performance reasons every operation that can be performed on any element or level in the structure is always performed in the scope of the main (root) document.

Re-writing code to use PL/SQL AP Documents instead of the obsolete Records API is quite straight forward, but may sometimes require changes in order of creating the structure. For example it is possible to add a record as an aggregate to another record where both records are created independently, while the aggregated document has to be created in scope of the main document.

Element names

Because PL/SQL AP Documents are serialized to/from XML and the document element names then correspond to XML element (tag) names, there are some limitations on element names defined in the XML specification:

The Plsqlap_Document_API package validates element names according to the above rules.

Examples

Creating a Record with some simple attributes:

rec_ := PLSQLAP_Record_API.New_record('TEST_ORDER');

PLSQLAP_Record_API.Set_Value(rec_, 'COMPANY', 'AB', PLSQLAP_Record_API.dt_Text);
PLSQLAP_Record_API.Set_Value(rec_, 'ORDER_NO', 10001, PLSQLAP_Record_API.dt_Integer);
PLSQLAP_Record_API.Set_Value(rec_, 'DELIVERY_DATE', date_, PLSQLAP_Record_API.dt_Date);

Corresponding code that uses the PL/SQL AP Document API:

doc_ := PLSQLAP_Document_API.New_Document('TEST_ORDER');

PLSQLAP_Document_API.Add_Attribute(doc_, 'COMPANY', 'AB');
PLSQLAP_Document_API.Add_Attribute(doc_, 'ORDER_NO', 10001, type_ => PLSQLAP_Document_API.TYPE_INTEGER);
PLSQLAP_Document_API.Add_Attribute(doc_, 'DELIVERY_DATE', date_, type_ => PLSQLAP_Document_API.TYPE_DATE);

Adding an aggregate to a Record:

agg_ := PLSQLAP_Record_API.New_record('ADDRESS');

PLSQLAP_Record_API.Set_Value(agg_, 'STREET', 'Gullbergs Strandgata 15', PLSQLAP_Record_API.dt_Text);
PLSQLAP_Record_API.Set_Value(agg_, 'CITY', 'Gothenburg', PLSQLAP_Record_API.dt_Text);
Plsqlap_Record_API.Add_Aggregate(rec_, 'DELIVERY_ADDR', agg_);

Adding an aggregate to a Document:

id_ := PLSQLAP_Document_API.Add_Aggregate(doc_, 'DELIVERY_ADDR', 'ADDRESS');

PLSQLAP_Document_API.Add_Attribute(doc_, 'STREET', 'Gullbergs Strandgata 15', id_);
PLSQLAP_Document_API.Add_Attribute(doc_, 'CITY', 'Gothenburg', id_);

Note the difference when adding aggregates. When working with Record API you just create a new Record and add it to the main Record first when it is complete. Quite often developers create new functions that simply return the newly created record that is supposed to be added as an aggregate to another record. This approach will not work with documents. Everything has to be always created in the context of the main document, so the document has to be passed as an IN OUT parameter to such subroutine.

Adding an array to a Record:

FOR i_ in 1..3 LOOP
   det_ := PLSQLAP_Record_API.New_record('ITEM');
   PLSQLAP_Record_API.Set_Value(det_, 'PROD_ID', 'C0'||i_, PLSQLAP_Record_API.dt_Text);
   PLSQLAP_Record_API.Set_Value(det_, 'AMOUNT', 100*i_, PLSQLAP_Record_API.dt_Integer);
   PLSQLAP_Record_API.Add_Array(rec_,'ORDER_ITEMS', det_);
END LOOP;

Adding an array to a Document:

arr_ := PLSQLAP_Document_API.Add_Array(doc_, 'ORDER_ITEMS');
FOR i_ in 1..3 LOOP
   id_ := PLSQLAP_Document_API.Add_Document(doc_, 'ITEM', arr_);
   PLSQLAP_Document_API.Add_Attribute(doc_, 'PROD_ID', 'C0'||i_, id_);
   PLSQLAP_Document_API.Add_Attribute(doc_, 'AMOUNT', 100*i_, id_, PLSQLAP_Document_API.TYPE_INTEGER);
END LOOP;

Even is the main goal of Plsqlap_Document_API package is creation and maintenance of documents that are supposed to be sent and retrieved using methods in Plsqlap_Server_API, it is also possible to use the package to work with XML documents that contain additional information and/or don't comply to IFS XML specification.

Procedure Add_Xml_Attribute can be used to add optional XML attributes to an arbitrary element in the structure. Because of that all Add_Attribute methods exist as both procedures and functions that return ID of the attribute that can then be sent as parameter to Add_Xml_Attribute. Those additional XML attributes will be present in the XML created with the To_Xml procedure if the xml_attrs_ parameter is set to TRUE.
By default IFS XML contains additional level for aggregates and arrays ('DELIVERY_ADDR' and 'ORDER_ITEMS' in examples above). To skip this additional level when creating an XML document set the value of the agg_level_ parameter to FALSE in call to To_Xml.

Fetching values from a Document can be done in several ways. While the Record API has practically only one method Get_Value and handling of different types has to be done by the developer, the PL/SQL AP Document API offers a version for each type. All Get_Value functions require ID of the attribute they are supposed to fetch value form. The ID can be obtained in several ways. Functions Find_Element_Id and Get_Element_Id return ID of a named attribute within a document, but they can also search in deep in the structure if the path_ parameter is representing a search path with slashes ('/') as name separators. If the path_ is pointing an element within an array, the first element in the array will be referred. The Find_Element_Id function will return NULL if the element is not found, while the Get_Element_Id will raise an exception in the same situation. There are also overloaded versions of all Get_Value functions that take path_ instead of ID as argument - those function just call Find_Element_Id internally. Note that those versions of functions can return NULL in two situations: the value of the searched attribute is NULL or the attribute is not found.

Especially when working with arrays it can be necessary to iterate through all elements in the array. The function Get_Child_Elements returns a collection (a table) with a list of of all child element IDs of a given element. An overloaded version of this function takes path_ as argument.

Some examples of how to fetch values:

val_ := PLSQLAP_Document_API.Get_Value(doc_, PLSQLAP_Document_API.Get_Element_Id(doc_, 'COMPANY'));
dbms_output.put_line('COMPANY='||val_);

val_ := PLSQLAP_Document_API.Get_Value(doc_, PLSQLAP_Document_API.Get_Element_Id(doc_, 'ORDER_ITEMS/ITEM/PROD_ID'));
dbms_output.put_line('First PRODUCT ID='||val_);

id_ := PLSQLAP_Document_API.Get_Element_Id(doc_, 'ORDER_ITEMS');
list_ := PLSQLAP_Document_API.Get_Child_Elements(doc_, id_);
for i in 1..list_.count loop
   list2_ := PLSQLAP_Document_API.Get_Child_Elements(doc_, list_(i));
   for j in 1..list2_.count loop
      id_ := list2_(j);
      if PLSQLAP_Document_API.Get_Name(doc_, id_) = 'AMOUNT' then
         num_val_ := PLSQLAP_Document_API.Get_Number_Value(doc_, id_);
         dbms_output.put_line('AMOUNT('||i||')='||num_val_);
      end if;
   end loop;
end loop;

The above example will raise an exception if any of those searched attributes can not be found. The same block can be written as follow using the overloaded versions of functions:

val_ := PLSQLAP_Document_API.Get_Value(doc_, 'COMPANY'); -- will return NULL if COMPANY not found
dbms_output.put_line('COMPANY='||val_);

val_ := PLSQLAP_Document_API.Get_Value(doc_, 'ORDER_ITEMS/ITEM/PROD_ID'); -- will return NULL if the attribute can not be found
dbms_output.put_line('First PRODUCT ID='||val_);

list_ := PLSQLAP_Document_API.Get_Child_Elements(doc_, 'ORDER_ITEMS'); -- will return empty collection if ORDER_ITEMS can not be found
for i in 1..list_.count loop
   list2_ := PLSQLAP_Document_API.Get_Child_Elements(doc_, list_(i));
   for j in 1..list2_.count loop
      id_ := list2_(j);
      if PLSQLAP_Document_API.Get_Name(doc_, id_) = 'AMOUNT' then
         num_val_ := PLSQLAP_Document_API.Get_Number_Value(doc_, id_);
         dbms_output.put_line('AMOUNT('||i||')='||num_val_);
      end if;
   end loop;
end loop;

Data Types and Constants

Constants defining possible data types of attributes:

TYPE_TEXTText represented by VARCHAR2 or CLOB in PL/SQL
TYPE_INTEGERInteger represented by NUMBER in PL/SQL
TYPE_FLOATFloat represented by NUMBER in PL/SQL
TYPE_BOOLEANBoolean represented as BOOLEAN in PL/SQL
TYPE_BINARYBinary represented as BLOB in PL/SQL
TYPE_DATEDate represented as DATE in PL/SQL
TYPE_TIMETime represented as DATE in PL/SQL
TYPE_TIMESTAMPTimestamp represented as DATE in PL/SQL
TYPE_COMPOUNDDenotes a compound attribute, i.e. an aggregate or array
TYPE_DOCUMENTDenotes element (document) of a compound attribute

Public types:

Element_IDUsed to represent ID of any element in the document structure.
DocumentRecord type representing the entire document. Note that content of the record is an implementation detail and may not be directly changed or accessed.
Child_TableCollection (TABLE) of element IDs that represent child (nested) elements of a given element. Child elements to a document on any level are attributes, simple or compound. Child elements to a compound attribute are documents. Simple attributes do not have any child elements.
Xml_AttributeRecord type representing an optional XML attribute (not used by the IFS framework). The record contains only two fields:
name  VARCHAR2(200),
value VARCHAR2(4000)
Xml_Attr_TableCollection (TABLE) of Xml_Attribute that represents all optional XML attributes for a given element.

Public methods

Create a new document

FUNCTION New_Document (
   name_      IN VARCHAR2,
   array_     IN BOOLEAN  DEFAULT FALSE,
   namespace_ IN VARCHAR2 DEFAULT NULL ) RETURN Document

PROCEDURE New_Document (
   main_      OUT Document,
   name_      IN  VARCHAR2,
   array_     IN  BOOLEAN  DEFAULT FALSE,
   namespace_ IN  VARCHAR2 DEFAULT NULL )

Parameters:


Add an attribute to a document

FUNCTION Add_Attribute (
   main_      IN OUT Document,
   name_      IN     VARCHAR2,
   value_     IN     <one of: VARCHAR2, CLOB, BOOLEAN, BLOB>,
   parent_id_ IN     Element_Id DEFAULT NULL,
   namespace_ IN     VARCHAR2   DEFAULT NULL ) RETURN Element_Id

PROCEDURE Add_Attribute (
   main_      IN OUT Document,
   name_      IN     VARCHAR2,
   value_     IN     <one of: VARCHAR2, CLOB, BOOLEAN, BLOB>,
   parent_id_ IN     Element_Id DEFAULT NULL,
   namespace_ IN     VARCHAR2   DEFAULT NULL )

FUNCTION Add_Attribute (
   main_      IN OUT Document,
   name_      IN     VARCHAR2,
   value_     IN     <one of: NUMBER, DATE>,
   parent_id_ IN     Element_Id DEFAULT NULL,
   type_      IN     VARCHAR2   DEFAULT <depends on value type>,
   namespace_ IN     VARCHAR2   DEFAULT NULL ) RETURN Element_Id

PROCEDURE Add_Attribute (
   main_      IN OUT Document,
   name_      IN     VARCHAR2,
   value_     IN     <one of: NUMBER, DATE>.
   parent_id_ IN     Element_Id DEFAULT NULL,
   type_      IN     VARCHAR2   DEFAULT <depends on value type>,
   namespace_ IN     VARCHAR2   DEFAULT NULL )

Parameters:

In case you need to add optional XML attributes you can use the function instead of procedure to directly obtain ID of the created attribute that can be used in call to Add_Xml_Attribute.


Add an aggregate (a compound attribute) to a document

FUNCTION Add_Aggregate (
   main_          IN OUT Document,
   name_          IN     VARCHAR2,
   doc_name_      IN     VARCHAR2,
   parent_id_     IN     Element_Id DEFAULT NULL,
   namespace_     IN     VARCHAR2   DEFAULT NULL,
   doc_namespace_ IN     VARCHAR2   DEFAULT NULL ) RETURN Element_Id

 FUNCTION Add_Aggregate (
   main_          IN OUT Document,
   doc_name_      IN     VARCHAR2,
   parent_id_     IN     Element_Id DEFAULT NULL,
   namespace_     IN     VARCHAR2   DEFAULT NULL,
   doc_namespace_ IN     VARCHAR2   DEFAULT NULL ) RETURN Element_Id

Parameters:

Note that there is no difference between an aggregate and an array with one element. This method does the same as a sequence Add_Array and then Add_Document.


Add an array (a compound attribute) to a document

FUNCTION Add_Array (
   main_      IN OUT Document,
   name_      IN     VARCHAR2,
   parent_id_ IN     Element_Id DEFAULT NULL,
   namespace_ IN     VARCHAR2   DEFAULT NULL ) RETURN Element_Id

Parameters:


Add a document to an array (compound attribute)

FUNCTION Add_Document (
   main_      IN OUT Document,
   name_      IN     VARCHAR2,
   array_id_  IN     Element_Id DEFAULT NULL,
   namespace_ IN     VARCHAR2   DEFAULT NULL) RETURN Element_Id

Parameters:


Add an optional XML attribute to an element

Note that XML attributes are not used by the IFS framework.

PROCEDURE Add_Xml_Attribute (
   main_  IN OUT Document,
   id_    IN     Element_Id,
   name_  IN     VARCHAR2,
   value_ IN     VARCHAR2 )

PROCEDURE Add_Xml_Attribute (
   main_  IN OUT Document,
   name_  IN     VARCHAR2,
   value_ IN     VARCHAR2 )

Parameters:


Return ID of the root element

FUNCTION Get_Root_Id (
   main_ IN Document ) RETURN Element_Id

Parameters:


Retrieve the total number of elements

FUNCTION Get_Element_Count (
   main_ IN Document ) RETURN BINARY_INTEGER

Parameters:


Find an ID of an element denoted by its path

FUNCTION Find_Element_Id (
   main_      IN Document,
   path_      IN VARCHAR2,
   parent_id_ IN Element_Id ) RETURN Element_Id

FUNCTION Find_Element_Id (
   main_      IN Document,
   path_      IN VARCHAR2 ) RETURN Element_Id

FUNCTION Get_Element_Id (
   main_      IN Document,
   path_      IN VARCHAR2,
   parent_id_ IN Element_Id ) RETURN Element_Id

FUNCTION Get_Element_Id (
   main_      IN Document,
   path_      IN VARCHAR2 ) RETURN Element_Id

Parameters:


Obtain value of an attribute

FUNCTION Get_Value (
   main_  IN Document,
   id_    IN Element_Id ) RETURN VARCHAR2

FUNCTION Get_Number_Value (
   main_  IN Document,
   id_    IN Element_Id ) RETURN NUMBER

FUNCTION Get_Boolean_Value (
   main_  IN Document,
   id_    IN Element_Id ) RETURN BOOLEAN

FUNCTION Get_Date_Value (
   main_  IN Document,
   id_    IN Element_Id ) RETURN DATE

FUNCTION Get_Time_Value (
   main_  IN Document,
   id_    IN Element_Id ) RETURN DATE

FUNCTION Get_Timestamp_Value (
   main_  IN Document,
   id_    IN Element_Id ) RETURN DATE

FUNCTION Get_Clob_Value (
   main_  IN Document,
   id_    IN Element_Id ) RETURN CLOB

FUNCTION Get_Blob_Value (
   main_  IN Document,
   id_    IN Element_Id ) RETURN BLOB

Parameters:


Overloaded versions that internally call Find_Element_Id:

FUNCTION Get_Value (
   main_      IN Document,
   path_      IN VARCHAR2,
   parent_id_ IN Element_Id ) RETURN VARCHAR2

FUNCTION Get_Value (
   main_      IN Document,
   path_      IN VARCHAR2 ) RETURN VARCHAR2

FUNCTION Get_Number_Value (
   main_      IN Document,
   path_      IN VARCHAR2,
   parent_id_ IN Element_Id ) RETURN NUMBER

FUNCTION Get_Number_Value (
   main_      IN Document,
   path_      IN VARCHAR2 ) RETURN NUMBER

FUNCTION Get_Boolean_Value (
   main_      IN Document,
   path_      IN VARCHAR2,
   parent_id_ IN Element_Id ) RETURN BOOLEAN

FUNCTION Get_Boolean_Value (
   main_      IN Document,
   path_      IN VARCHAR2 ) RETURN BOOLEAN

FUNCTION Get_Date_Value (
   main_      IN Document,
   path_      IN VARCHAR2,
   parent_id_ IN Element_Id ) RETURN DATE

FUNCTION Get_Date_Value (
   main_      IN Document,
   path_      IN VARCHAR2 ) RETURN DATE

FUNCTION Get_Time_Value (
   main_      IN Document,
   path_      IN VARCHAR2,
   parent_id_ IN Element_Id ) RETURN DATE

FUNCTION Get_Time_Value (
   main_      IN Document,
   path_      IN VARCHAR2 ) RETURN DATE

FUNCTION Get_Timestamp_Value (
   main_      IN Document,
   path_      IN VARCHAR2,
   parent_id_ IN Element_Id ) RETURN DATE

FUNCTION Get_Timestamp_Value (
   main_      IN Document,
   path_      IN VARCHAR2 ) RETURN DATE

FUNCTION Get_Clob_Value (
   main_      IN Document,
   path_      IN VARCHAR2,
   parent_id_ IN Element_Id ) RETURN CLOB

FUNCTION Get_Clob_Value (
   main_      IN Document,
   path_      IN VARCHAR2 ) RETURN CLOB

FUNCTION Get_Blob_Value (
   main_      IN Document,
   path_      IN VARCHAR2,
   parent_id_ IN Element_Id ) RETURN BLOB

FUNCTION Get_Blob_Value (
   main_      IN Document,
   path_      IN VARCHAR2 ) RETURN BLOB

Parameters:

Change value of an attribute

PROCEDURE Set_Value (
   main_  IN OUT Document,
   id_    IN     Element_Id,
   value_ IN     <one of: VARCHAR2, CLOB, BOOLEAN, BLOB> )

PROCEDURE Set_Value (
   main_  IN OUT Document,
   id_    IN     Element_Id,
   value_ IN     <one of: NUMBER, DATE>,
   type_  IN     VARCHAR2 DEFAULT <depends on value type> )

Parameters:


Obtain value of an optional XML attribute

FUNCTION Get_Xml_Attribute (
   main_ IN Document,
   id_   IN Element_Id,
   name_ IN VARCHAR2 ) RETURN VARCHAR2

FUNCTION Get_Xml_Attribute (
   main_ IN Document,
   name_ IN VARCHAR2 ) RETURN VARCHAR2

Parameters:


Fetch all optional XML attributes for an element

FUNCTION Get_Xml_Attributes (
   main_ IN Document,
   id_   IN Element_Id ) RETURN Xml_Attr_Table

FUNCTION Get_Xml_Attributes (
   main_ IN Document ) RETURN Xml_Attr_Table

Parameters:


Change value of an optional XML attribute

PROCEDURE Set_Xml_Attribute (
   main_  IN OUT Document,
   id_    IN     Element_Id,
   name_  IN     VARCHAR2,
   value_ IN     VARCHAR2 )

PROCEDURE Set_Xml_Attribute (
   main_  IN OUT Document,
   name_  IN     VARCHAR2,
   value_ IN     VARCHAR2 )

Parameters:


Check if a document has been initialized, i.e. has been created by New_Document

FUNCTION Is_Initialized (
   main_ IN Document ) RETURN BOOLEAN

Parameters:


Check if an element is a simple attribute

FUNCTION Is_Simple (
   main_  IN Document,
   id_    IN Element_Id ) RETURN BOOLEAN

Parameterss:


Check if an element is a compound attribute, i.e. array or aggregate

FUNCTION Is_Compound (
   main_  IN Document,
   id_    IN Element_Id ) RETURN BOOLEAN

Parameterss:


Check if an element is a document

FUNCTION Is_Document (
   main_  IN Document,
   id_    IN Element_Id ) RETURN BOOLEAN

Parameterss:


Check if value of a simple attribute is NULL

FUNCTION Is_Null (
   main_  IN Document,
   id_    IN Element_Id ) RETURN BOOLEAN

Parameters:


Return name of an element

FUNCTION Get_Name (
   main_  IN Document,
   id_    IN Element_Id ) RETURN VARCHAR2

FUNCTION Get_Document_Name (
   main_  IN Document ) RETURN VARCHAR2

Parameters:


Obtain optional namespace name of a given element

FUNCTION Get_Namespace (
   main_  IN Document,
   id_    IN Element_Id) RETURN VARCHAR2

Parameters:


Obtain type name of a given element

FUNCTION Get_Type (
   main_  IN Document,
   id_    IN Element_Id ) RETURN VARCHAR2

Parameters:


Fetch child elements of a given element

FUNCTION Get_Child_Elements (
   main_  IN Document,
   id_    IN Element_Id ) RETURN Child_Table

FUNCTION Get_Child_Elements (
   main_  IN Document ) RETURN Child_Table

Parameters:


Overloaded versions that internally call Find_Element_Id:

FUNCTION Get_Child_Elements (
   main_      IN Document,
   path_      IN VARCHAR2,
   parent_id_ IN Element_Id ) RETURN Child_Table

FUNCTION Get_Child_Elements (
   main_      IN Document,
   path_      IN VARCHAR2 ) RETURN Child_Table

Parameters:


Renaming elements

Renaming a single element:

PROCEDURE Rename (
   main_  IN OUT Document,
   id_    IN     Element_Id,
   name_  IN     VARCHAR2 )

Parameters:


Bulk renaming of elements:

PROCEDURE Rename (
   main_     IN OUT Document,
   from_     IN     VARCHAR2,
   to_       IN     VARCHAR2,
   simple_   IN     BOOLEAN DEFAULT FALSE,
   compound_ IN     BOOLEAN DEFAULT FALSE,
   document_ IN     BOOLEAN DEFAULT FALSE )

Parameters:


Convert all element names from IFS XML syntax (uppercase with underscores) to camel case:

PROCEDURE To_Camel_Case (
   main_       IN OUT Document,
   init_upper_ IN     BOOLEAN DEFAULT TRUE,
   namespace_  IN     BOOLEAN DEFAULT FALSE )

This procedure starts with replacing all dots and dashes with underscores and removing all initial and trailing underscores. All words are then renamed to lower case with initial letter in upper case using underscores as word delimiters.

Parameters:


Convert all element names from camel case to upper case with underscores (IFS XML):

PROCEDURE To_Upper_Case (
   main_      IN OUT Document,
   namespace_ IN     BOOLEAN DEFAULT FALSE )

This procedure starts with removing all underscores, dots and dashes and then for each upper case letter puts an underscore before the letter. Finally the result is converted to upper case.

Parameters:


Note the the two procedures, To_Camel_Case and To_Upper_Case are not unambiguous. There is no 1:1 relationship between the original name and the new one. With other words applying both procedures in sequence on a document will not revert the document to it's origin. Applying the same function twice or applying on a document of unexpected format can lead to unexpected result.


Remove namespaces

Removes namespaces from the entire documents. Also deletes xmlns XML attributes.

PROCEDURE Remove_Namespaces (
   main_ IN OUT Document)

Parameters:


Serialize document to a JSON structure

PROCEDURE To_Json (
   json_     OUT CLOB,
   main_     IN  Document,
   indent_   IN  NUMBER DEFAULT NULL,
   use_crlf_ IN BOOLEAN DEFAULT FALSE )

Parameters:


Serialize document to an XML document

PROCEDURE To_Xml (
   xml_        OUT CLOB,
   main_       IN  Document,
   agg_level_  IN  BOOLEAN    DEFAULT TRUE,
   xml_attrs_  IN  BOOLEAN    DEFAULT FALSE,
   id_         IN  Element_Id DEFAULT NULL,
   elem_type_  IN  BOOLEAN    DEFAULT FALSE,
   add_header_ IN  BOOLEAN    DEFAULT FALSE,
   indent_     IN  NUMBER     DEFAULT NULL,
   use_crlf_   IN  BOOLEAN    DEFAULT FALSE,
   namespaces_ IN  BOOLEAN    DEFAULT FALSE )

Parameters:


Serialize document to an IFS XML document

PROCEDURE To_Ifs_Xml (
   xml_        OUT CLOB,
   main_       IN  Document,
   id_         IN  Element_Id DEFAULT NULL,
   add_type_   IN  BOOLEAN    DEFAULT FALSE,
   add_header_ IN  BOOLEAN    DEFAULT FALSE,
   indent_     IN  NUMBER     DEFAULT NULL,
   use_crlf_   IN  BOOLEAN    DEFAULT FALSE )

Parameters:


Parse an XML document to a document

PROCEDURE From_Xml (
   main_       OUT Document,
   xml_        IN  CLOB,
   agg_level_  IN  BOOLEAN  DEFAULT TRUE,
   add_type_   IN  BOOLEAN  DEFAULT FALSE,
   agg_suffix_ IN  VARCHAR2 DEFAULT '_AGG' )

Parameters:

This procedure parses also the optional XML attributes.

Example

Consider the following XML document:

<ORDER>
  <LINES>
    <ITEM>
      <ITEM_NO>1</ITEM_NO>
      <ORDER_ARTICLE>
        <PRODUCT>
          <DESCRIPTION>Hard Disk</DESCRIPTION>
          <PRICE>60</PRICE>
        </PRODUCT>
      </ORDER_ARTICLE>
      <AMOUNT>10</AMOUNT>
    </ITEM>
    <ITEM>
      <ITEM_NO>2</ITEM_NO>
      <ORDER_ARTICLE>
        <PRODUCT>
          <DESCRIPTION>Computer</DESCRIPTION>
          <PRICE>100</PRICE>
        </PRODUCT>
      </ORDER_ARTICLE>
      <AMOUNT>3</AMOUNT>
    </ITEM>
  </LINES>
</ORDER>

This document complies to IFS XML standard (a document consists of attributes, simple and/or compound, a compound attribute contains one or more documents), so we can parse it to a PL/SQL AP Document using both From_Xml and From_Ifs_Xml (recommended for performance reasons). Documents are written in blue, simple attributes in green and compound attributes in red. The document structure after parsing will be as follow (based on output from the Debug procedure):

[ORDER]
.[LINES]
..[ITEM]
...[ITEM_NO]
...[ORDER_ARTICLE]
....[PRODUCT]
.....[DESCRIPTION]
.....[PRICE]
...[AMOUNT]
..[ITEM]
...[ITEM_NO]
...[ORDER_ARTICLE]
....[PRODUCT]
.....[DESCRIPTION]
.....[PRICE]
...[AMOUNT]

Document ORDER has only one, compound attribute, LINES. The compound attribute LINES consists of two instances of document ITEM. The ITEM document has two simple attributes, ITEM_NO and AMOUNT and one compound attribute ORDER_ARTICLE. The ORDER_ARTICLE attribute contains document PRODUCT, which, in turn, contains two simple attributes, DESCRIPTION and PRICE.

Suppose we want to extract some attributes from each item:

DECLARE
   doc_     Plsqlap_Document_API.Document;
   items_   Plsqlap_Document_API.Child_Table;
   xml_     CLOB := '...';
   item_no_ NUMBER;
   desc_    VARCHAR2(100);
BEGIN
   Plsqlap_Document_API.From_Ifs_Xml(doc_, xml_);
   items_ := Plsqlap_Document_API.Get_Child_Elements(doc_, 'LINES');
   FOR i IN 1..items_.count LOOP
      item_no_ := Plsqlap_Document_API.Get_Number_Value(doc_, 'ITEM_NO', items_(i));
      desc_    := Plsqlap_Document_API.Get_Value(doc_, 'ORDER_ARTICLE/PRODUCT/DESCRIPTION', items_(i));
      Dbms_Output.Put_Line('Found order item #'||item_no_||' with article "'||desc_||'".');
   END LOOP;
END;

The above code will result in the following output:

Found order item #1 with article "Hard Disk".
Found order item #2 with article "Computer".

Now we have another XML document:

<ORDER>
  <LINES>
    <ITEM>
      <ITEM_NO>1</ITEM_NO>
      <PRODUCT>
        <DESCRIPTION>Hard Disk</DESCRIPTION>
        <PRICE>60</PRICE>
      </PRODUCT>
      <AMOUNT>10</AMOUNT>
    </ITEM>
    <ITEM>
      <ITEM_NO>2</ITEM_NO>
      <PRODUCT>
        <DESCRIPTION>Computer</DESCRIPTION>
        <PRICE>100</PRICE>
      </PRODUCT>
      <AMOUNT>3</AMOUNT>
    </ITEM>
  </LINES>
</ORDER>

The only difference, compared to the previous example, is that we don't have the additional aggregate (compound attribute) level for ORDER_ARTICLE. The XML document doesn't comply to IFS XML any longer, so to parse it to a valid PL/SQL AP Document we need to use the From_Xml procedure with agg_level_ set to FALSE, which will cause adding the additional level for compound attributes using document names suffixed, by default, with "_AGG". I.e. the parser will assume the document consisting of documents and simple attributes only, no compound attributes at all.

The resulting structure will be then as follow:

[ORDER]
.[LINES_AGG]
..[LINES]
...[ITEM_AGG]
....[ITEM]
.....[ITEM_NO]
.....[PRODUCT_AGG]
......[PRODUCT]
.......[DESCRIPTION]
.......[PRICE]
.....[AMOUNT]
....[ITEM]
.....[ITEM_NO]
.....[PRODUCT_AGG]
......[PRODUCT]
.......[DESCRIPTION]
.......[PRICE]
.....[AMOUNT]

The difference is that the compound attribute ORDER_ARTICLE from the previous example has been replaced with a generated one with name PRODUCT_AGG and the compound attribute LINES is now treated as document. It results in generation of two additional compound attributes: ITEM_AGG, that now contains two instances of the ITEM document, and LINES_AGG that simply contains an instance of LINES, which is now treated as document.

The Document can then be serialized to the following XML document using the To_Ifs_Xml procedure:

<ORDER>
  <LINES_AGG>
    <LINES>
      <ITEM_AGG>
        <ITEM>
          <ITEM_NO>1</ITEM_NO>
          <PRODUCT_AGG>
            <PRODUCT>
              <DESCRIPTION>Hard Disk</DESCRIPTION>
              <PRICE>60</PRICE>
            </PRODUCT>
          </PRODUCT_AGG>
          <AMOUNT>10</AMOUNT>
        </ITEM>
        <ITEM>
          <ITEM_NO>2</ITEM_NO>
          <PRODUCT_AGG>
            <PRODUCT>
              <DESCRIPTION>Computer</DESCRIPTION>
              <PRICE>100</PRICE>
            </PRODUCT>
          </PRODUCT_AGG>
          <AMOUNT>3</AMOUNT>
        </ITEM>
      </ITEM_AGG>
    </LINES>
  </LINES_AGG>
</ORDER>

If we want to extract the same attributes as before the code has to be slightly changed (changes marked in bold):

DECLARE
   doc_     Plsqlap_Document_API.Document;
   items_   Plsqlap_Document_API.Child_Table;
   xml_     CLOB := '...';
   item_no_ NUMBER;
   desc_    VARCHAR2(100);
BEGIN
   Plsqlap_Document_API.From_Xml(doc_, xml_, agg_level_ => FALSE);
   items_ := Plsqlap_Document_API.Get_Child_Elements(doc_, 'LINES_AGG/LINES/ITEM_AGG');
   FOR i IN 1..items_.count LOOP
      item_no_ := Plsqlap_Document_API.Get_Number_Value(doc_, 'ITEM_NO', items_(i));
      desc_    := Plsqlap_Document_API.Get_Value(doc_, 'PRODUCT_AGG/PRODUCT/DESCRIPTION', items_(i));
      Dbms_Output.Put_Line('Found order item #'||item_no_||' with article "'||desc_||'".');
   END LOOP;
END;

Then the output will be the same as before.


Parse an IFS XML document to a document

PROCEDURE From_Ifs_Xml (
   main_ OUT Document,
   xml_  IN  CLOB )

Parameters:

Note that the procedure will not parse the optional XML attributes, nor the 'type' attribute.


Clear the document

PROCEDURE Clear (
   main_ IN OUT Document )

Parameters:

The document will be un-initialized. Normally it is not necessary to clear a document.


Debug document

PROCEDURE Debug  (
   main_ IN Document )

Parameters:

If document has been initialized and Foundation level is set to debug (the Log_SYS package), the procedure will list all elements in separate lines according to the pattern:

[<name>/<ID>,<parent_ID>/<type>:<list_of_child_element_ids>]='<value>'

List of child element IDs will be only shown for compound elements. Value will be appended only for simple attributes and not more then 50 characters. Elements will be indented according to their level in the document structure.