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.
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.
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.
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;
Constants defining possible data types of attributes:
TYPE_TEXT | Text represented by VARCHAR2 or
CLOB in PL/SQL |
TYPE_INTEGER | Integer represented by NUMBER in PL/SQL |
TYPE_FLOAT | Float represented by NUMBER in PL/SQL |
TYPE_BOOLEAN | Boolean represented as BOOLEAN in PL/SQL |
TYPE_BINARY | Binary represented as BLOB in PL/SQL |
TYPE_DATE | Date represented as DATE in PL/SQL |
TYPE_TIME | Time represented as DATE in PL/SQL |
TYPE_TIMESTAMP | Timestamp represented as DATE in PL/SQL |
TYPE_COMPOUND | Denotes a compound attribute, i.e. an aggregate or array |
TYPE_DOCUMENT | Denotes element (document) of a compound attribute |
Public types:
Element_ID | Used to represent ID of any element in the document structure. |
Document | Record type representing the entire document. Note that content of the record is an implementation detail and may not be directly changed or accessed. |
Child_Table | Collection (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_Attribute | Record type representing an optional
XML attribute (not used by the IFS framework). The record contains only two
fields:name VARCHAR2(200), |
Xml_Attr_Table | Collection (TABLE) of Xml_Attribute that represents
all optional XML attributes for a given element. |
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:
TRUE
create an array of documents rather
then a single 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:
BLOB
) are always encoded to
Base64 text. If the text is shorter then 32767 bytes, it will be stored as
VARCHAR2
, even if the parameter's data type is CLOB
or
BLOB
.NULL
the attribute will be added to the main document, i.e. on the top level in the structure.NUMBER
and DATE
as data type for value_. Allowed subtypes for
NUMBER
are TYPE_INTEGER
and TYPE_FLOAT
(default) and for
DATE
are TYPE_DATE
, TYPE_TIME
and
TYPE_TIMESTAMP
(default).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.
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:
NULL
the attribute will be added to the main document, i.e. on the top level in the structure.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.
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:
NULL
the attribute will be added to the main document, i.e. on the top level in the structure.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:
NULL
and the main document is created as an array (with
array_ argument to the
New_Document set to TRUE
),
the document will be added to the top level array.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:
id_
parameter adds the
attribute to the main (root) element.FUNCTION Get_Root_Id ( main_ IN Document ) RETURN Element_Id
Parameters:
FUNCTION Get_Element_Count ( main_ IN Document ) RETURN BINARY_INTEGER
Parameters:
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:
/
') starting from the element given by
parent_id_. The algorithm will start searching in child elements to the element given by
parent_id_, so the name of the top level element shall not be included. If the search path includes elements within an array, the first element in the array will be taken.NULL
while Get_Element_Id will raise an exception.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:
BLOB
) are supposed to be stored as a
Base64 encoded text. For Boolean values NULL
is treated as
FALSE
.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:
/
')
starting from the element given by parent_id_. The algorithm will start
searching in child elements to the element given by parent_id_ or from root
for versions of functions not expecting the parent_id_ parameter, so the
name of the top level element shall not be included. If the search path
includes elements within an array, the first element in the array will be
taken.BLOB
) are
supposed to be stored as a Base64 encoded text. For Boolean values
NULL
value is treated as FALSE
. If the element given by the path_ parameter is
not found, those functions will return NULL
.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:
BLOB
) are always encoded to
Base64 text. If the text is shorter then 32767 bytes, it will be stored as
VARCHAR2
, even if the parameter's data type is CLOB
or
BLOB
.NUMBER
and DATE
as data type for value_. Allowed subtypes for
NUMBER
are TYPE_INTEGER
and TYPE_FLOAT
(default) and for
DATE
are TYPE_DATE
, TYPE_TIME
and
TYPE_TIMESTAMP
(default).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:
id_
parameter
fetches the attribute from the main (root) element.NULL
if not
found.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:
id_
parameter
fetches attributes from the main (root) element.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:
id_
parameter
searches after the attribute in the main (root) element.FUNCTION Is_Initialized ( main_ IN Document ) RETURN BOOLEAN
Parameters:
TRUE
if the document has been initialized, FALSE
otherwise.FUNCTION Is_Simple ( main_ IN Document, id_ IN Element_Id ) RETURN BOOLEAN
Parameterss:
TRUE
if the element denoted by the given ID is a
simple attribute, i.e. an attribute that has a value,
FALSE
otherwise.FUNCTION Is_Compound ( main_ IN Document, id_ IN Element_Id ) RETURN BOOLEAN
Parameterss:
TRUE
if the element denoted by the given ID is a compound attribute, i.e. an array or aggregate,
FALSE
otherwise.FUNCTION Is_Document ( main_ IN Document, id_ IN Element_Id ) RETURN BOOLEAN
Parameterss:
TRUE
if the element denoted by the given ID is a document,
i.e. an element that contains attributes, simple or compound. Return FALSE
otherwise.FUNCTION Is_Null ( main_ IN Document, id_ IN Element_Id ) RETURN BOOLEAN
Parameters:
TRUE
if the element given by it's ID is a simple attribute and it's value is
NULL
. If the ID represents a compound attribute or document, an exception will be raised. In other cases the function will return
FALSE
.FUNCTION Get_Name ( main_ IN Document, id_ IN Element_Id ) RETURN VARCHAR2 FUNCTION Get_Document_Name ( main_ IN Document ) RETURN VARCHAR2
Parameters:
FUNCTION Get_Namespace ( main_ IN Document, id_ IN Element_Id) RETURN VARCHAR2
Parameters:
NULL
if not
defined.FUNCTION Get_Type ( main_ IN Document, id_ IN Element_Id ) RETURN VARCHAR2
Parameters:
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:
/
')
starting from the element given by parent_id_. The algorithm will start
searching in child elements to the element given by parent_id_ or from root
for version without parent_id_, so the
name of the top level element shall not be included. If the search path
includes elements within an array, the first element in the array will be
taken.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:
TRUE
simple attributes with name from_
will be renamed. Default FALSE
.TRUE
compound attributes (arrays and
aggregates) with name from_ will be renamed. Default FALSE
.TRUE
documents with name from_ will
be renamed. Default FALSE
.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:
TRUE
the first letter of the first
word will be in upper case, otherwise in lower case. Default TRUE
.TRUE
namespace names will also be renamed.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:
TRUE
namespace names will also be
renamed.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.
Removes namespaces from the entire documents. Also deletes xmlns
XML attributes.
PROCEDURE Remove_Namespaces ( main_ IN OUT Document)
Parameters:
PROCEDURE To_Json ( json_ OUT CLOB, main_ IN Document, indent_ IN NUMBER DEFAULT NULL, use_crlf_ IN BOOLEAN DEFAULT FALSE )
Parameters:
NULL
the entire XML will be generated
without any indentation and line breaks. A positive integer will cause
indentation according to the defined number. Value 0
only
causes adding line breaks. Default NULL
.LF
character (chr(10)
) to denote line breaks if indentation is
enabled. If this parameter is set to TRUE
the procedure will
use the character sequence CRLF
instead (chr(13) ||
chr(10)
).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:
FALSE
the additional level for compound attributes will be omitted, i.e. aggregate and array names will be skipped. Default
TRUE
.TRUE
the optional XML attributes will be added. Default
FALSE
.TRUE
the procedure will generate an XML attribute to each element with name 'type
' and value corresponding to the type of actual element. Note that the
xml_attrs_ parameter is then ignored. Default is FALSE
.TRUE
an XML document header will be added.NULL
the entire XML will be generated
without any indentation and line breaks. A positive integer will cause
indentation according to the defined number. Value 0
only
causes adding line breaks. Default NULL
.LF
character (chr(10)
) to denote line breaks if indentation is
enabled. If this parameter is set to TRUE
the procedure will
use the character sequence CRLF
instead (chr(13) ||
chr(10)
).TRUE
namespaces are also added.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:
TRUE
the procedure will generate an XML attribute to each element with name 'type
' and value corresponding to the type of actual element. Default is
FALSE
.TRUE
an XML document header will be added.NULL
the entire XML will be generated
without any indentation and line breaks. A positive integer will cause
indentation according to the defined number. Value 0
only
causes adding line breaks. Default NULL
.LF
character (chr(10)
) to denote line breaks if indentation is
enabled. If this parameter is set to TRUE
the procedure will
use the character sequence CRLF
instead (chr(13) ||
chr(10)
).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:
FALSE
, the parser will not expect the additional level for compound attributes (i.e. array and aggregate names) to be present in the parsed XML document. The compound attribute will be automatically created using the actual document (tag) name
suffixed with the value of the agg_suffix_ parameter. Default
TRUE
.TRUE
, element type will be set according to specification taken from the 'type
' XML attribute. Default
FALSE
.FALSE
, the
additional aggregate level will use this parameter to create the name of the
additional compound attribute by suffixing the document name with the value
of this attribute. Default is "_AGG
".This procedure parses also the optional XML attributes.
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.
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.
PROCEDURE Clear ( main_ IN OUT Document )
Parameters:
The document will be un-initialized. Normally it is not necessary to clear a 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.