Skip to content

Commit

Permalink
Merge pull request #6290 from EnterpriseDB/epas/domdoc_corrections
Browse files Browse the repository at this point in the history
EPAS: DBMS_XMLDOMDOC corrections
  • Loading branch information
nidhibhammar authored Dec 5, 2024
2 parents 3160a02 + 1605e4f commit e9e90c5
Show file tree
Hide file tree
Showing 38 changed files with 837 additions and 848 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ The `pgAgent` and `adminpack` packages are end of life from EPAS 17 and later.
|----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|
| Upstream merge | Merged with community PostgreSQL 17.2. See the [PostgreSQL 17 Release Notes](https://www.postgresql.org/docs/17/release-17-2.html) for more information. | |
| Feature | Added support for the Oracle-compatible `BFILE` native datatype and the `DBMS_LOB` package APIs. See the [DBMS_LOB](../reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/06_dbms_lob/) for more information. | |
| Feature | Added support for the Oracle-compatible `DBMS_XMLDOM` package to provide interface for HTML and XML documents. See the [DBMS_XMLDOM](../reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/dbms_xmldom) for more information. | |
| Feature | Added support for the Oracle-compatible `DBMS_XMLDOM` package to provide interface for HTML and XML documents. See the [DBMS_XMLDOM](../reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/18_dbms_xmldom) for more information. | |
| Feature | Added support for the Oracle-compatible `DBMS_ASSERT` package to validate input properties and sanitize user input, thereby reducing the risk of SQL injections. See the [DBMS_ASSERT](../reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/01a_dbms_assert) for more information. | |
| Feature | Added support for the Oracle-equivalent `NLS_UPPER`,`NLS_LOWER`, and `NLS_INITCAP` functions. See the [NLS functions](../reference/sql_reference/03_functions_and_operators/nls_functions) for more information. | |
| Feature | Implemented `alteruser` utility to modify roles in the clusters. See the [alteruser utility](/tools/alteruser_utility/) for more information. | |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
s---
---
title: "SUBSTR"
redirects:
- /epas/latest/epas_compat_bip_guide/03_built-in_packages/06_dbms_lob/11_substr/ #generated for docs/epas/reorg-role-use-case-mode
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: "APPENDCHILD"
---

The `APPENDCHILD` function adds the node at the end of the list of children of a particular node. It returns the newly added node and if the node is already present, it removes the existing node before adding new node.

You can append more than one child to a document node. However, a node cannot belong to several documents.

When appending elements, you cannot add an element to itself. Additionally, if the same element is added twice, only the latest is considered.

```
APPENDCHILD(n DOMNode, newChild IN DOMNode) RETURN DOMNode
```

## Parameters

`n`

The `DOMNode` where the new node is to be added.

`newchild`

The child node to be added to the existing list of children of node n.

## Examples

This example creates a new XML `DOMDocument` named `l_domdoc` and a new `DOMElement` named `l_department_element` with tag name `Departments`. It then appends the `DOMElement` as a child of the `DOMDocument`.

```sql
DECLARE
l_domdoc DBMS_XMLDOM.DOMDocument;
l_department_element DBMS_XMLDOM.DOMElement;
l_xmltype XMLTYPE;


BEGIN
l_domdoc := DBMS_XMLDOM.NEWDOMDOCUMENT();
l_department_element := DBMS_XMLDOM.CREATEELEMENT(l_domdoc, 'Departments' );
PERFORM DBMS_XMLDOM.appendChild(DBMS_XMLDOM.MAKENODE(l_domdoc), DBMS_XMLDOM.MAKENODE(l_department_element));
l_xmltype := DBMS_XMLDOM.GETXMLTYPE(l_domdoc);
DBMS_OUTPUT.PUT_LINE(l_xmltype.getStringVal());
END;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: "CREATEELEMENT"
---

The `CREATEELEMENT` function creates and returns a DOMElement.

```
CREATEELEMENT( doc DOMDocument, tagname IN VARCHAR2) RETURN DOMElement
```

## Parameters

`doc`

Any `DOMDocument`.

`tagname`

Tag name to be given to the new `DOMElement`.

## Examples

This example creates a new XML `DOMDocument` named `l_domdoc` and a new `DOMElement` named `l_department_element` with tag name `Departments`. It then appends the `DOMElement` as a child of the `DOMDocument`.

```sql
DECLARE
l_domdoc DBMS_XMLDOM.DOMDocument;
l_department_element DBMS_XMLDOM.DOMElement;
l_xmltype XMLTYPE;


BEGIN
l_domdoc := DBMS_XMLDOM.NEWDOMDOCUMENT();
l_department_element := DBMS_XMLDOM.CREATEELEMENT(l_domdoc, 'Departments' );
PERFORM DBMS_XMLDOM.APPENDCHILD(DBMS_XMLDOM.MAKENODE(l_domdoc), DBMS_XMLDOM.MAKENODE(l_department_element));
l_xmltype := DBMS_XMLDOM.GETXMLTYPE(l_domdoc);
DBMS_OUTPUT.PUT_LINE(l_xmltype.getStringVal());
END;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
title: "CREATETEXTNODE"
---

The `CREATETEXTNODE` function creates and returns a DOMText node.

```
CREATETEXTNODE( doc DOMDocument, data IN VARCHAR2) RETURN DOMText
```

## Parameters

`doc`

Any `DOMDocument`.

`data`

Content provided for the `DOMText` node.

## Examples

This example creates a new XML `DOMDocument`, a `DOMElement` with tag name “Departments” and a text node with “Depts list” as its value. The `DOMElement` is appended as a child to the `DOMDocument`, and the text node as a child to the `DOMElement`.

```sql
DECLARE
l_domdoc DBMS_XMLDOM.DOMDocument;
l_root_node DBMS_XMLDOM.DOMNode;
l_department_element DBMS_XMLDOM.DOMElement;
l_departments_node DBMS_XMLDOM.DOMNode;
l_name_text DBMS_XMLDOM.DOMText;
l_xmltype XMLTYPE;


BEGIN
l_domdoc := DBMS_XMLDOM.NEWDOMDOCUMENT;
l_root_node := DBMS_XMLDOM.MAKENODE(l_domdoc);
l_department_element := DBMS_XMLDOM.CREATEELEMENT(l_domdoc, 'Departments' );
l_departments_node := DBMS_XMLDOM.APPENDCHILD(l_root_node,DBMS_XMLDOM.MAKENODE(l_department_element));
l_name_text := DBMS_XMLDOM.CREATETEXTNODE(l_domdoc, 'Depts list' );
PERFORM DBMS_XMLDOM.APPENDCHILD(l_departments_node,DBMS_XMLDOM.MAKENODE(l_name_text));
l_xmltype := DBMS_XMLDOM.GETXMLTYPE(l_domdoc);
DBMS_OUTPUT.PUT_LINE(l_xmltype.getStringVal());
END;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
title: "FREEDOCUMENT"
---

The `FREEDOCUMENT` procedure is used to free the `DOMDocument` object.

```
FREEDOCUMENT(doc IN DOMDocument)
```

## Parameters

`doc`

The `DOMDocument` to be made free.


## Examples

This example creates a new `DOMDocument`, which is not accessible after it has been freed.

```sql
DECLARE
l_domdoc DBMS_XMLDOM.DOMDocument;


BEGIN
l_domdoc := DBMS_XMLDOM.NEWDOMDOCUMENT();
DBMS_XMLDOM.FREEDOCUMENT(l_domdoc);
DBMS_XMLDOM.SETVERSION(l_domdoc, '1.0');
END;
/
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
title: "GETATTRIBUTE"
---

The `GETATTRIBUTE` function returns the value of an attribute of an `DOMElement` by name.

```
GETATTRIBUTE(elem DOMElement, name IN VARCHAR2) RETURN VARCHAR2
GETATTRIBUTE(elem DOMElement, name IN VARCHAR2, ns IN VARCHAR2) RETURN VARCHAR2
```

## Parameters

`elem`

The `DOMElement` whose attribute value needs to be obtained.

`name`

The attribute name whose attribute value needs to be obtained.

`ns`

The namespace URI.

## Examples

This example creates a new `DOMDocument` named `l_domdoc`, and a `DOMElement` named `elem` with tag name “Departments”. It adds an attribute (`attr`) to the `DOMElement` with the value "value" and appends the `DOMElement` as a child of the `DOMDocument`.

The `get` subprogram returns the value of the attribute `attr` of the "Departments" element.


```sql
DECLARE
l_xml XMLType;
l_domdoc DBMS_XMLDOM.DOMDocument;
l_departments_node DBMS_XMLDOM.DOMNode;
elem DBMS_XMLDOM.DOMElement;
BEGIN
l_domdoc := DBMS_XMLDOM.NEWDOMDOCUMENT;
elem := DBMS_XMLDOM.CREATEELEMENT(l_domdoc, 'Departments' );
DBMS_XMLDOM.SETATTRIBUTE(elem, 'attr', 'value');
PERFORM DBMS_XMLDOM.APPENDCHILD(DBMS_XMLDOM.MAKENODE(l_domdoc), DBMS_XMLDOM.MAKENODE(elem));
l_xml := DBMS_XMLDOM.GETXMLTYPE(l_domdoc);
dbms_output.put_line(l_xml.getStringVal());
dbms_output.put_line(DBMS_XMLDOM.GETATTRIBUTE(elem, 'attr'));
END;
```

This example defines a namespace named “example” and uses an XMLtype string to create an XML structure. `GETFIRSTCHILD` then returns a `DOMNode` that represents a `DOMElement`. Since `GETATTRIBUTE` expects a `DOMElement`, the `MAKEELEMENT` function converts a specified `DOMNode` into a `DOMElement` and returns it.

```sql
DECLARE
l_domdoc DBMS_XMLDOM.DOMDocument;
l_departments_node DBMS_XMLDOM.DOMNode;
item_node DBMS_XMLDOM.DOMNode;
BEGIN
l_domdoc := DBMS_XMLDOM.NEWDOMDOCUMENT(XMLTYPE('<b:collection xmlns:b="example:namespace"><b:item b:type="primary" b:id="[email protected]"></b:item></b:collection>'));


l_departments_node := DBMS_XMLDOM.GETFIRSTCHILD(DBMS_XMLDOM.MAKENODE(l_domdoc));
item_node := DBMS_XMLDOM.GETFIRSTCHILD(l_departments_node);
dbms_output.put_line('item node: ' || DBMS_XMLDOM.GETNODENAME(item_node));
dbms_output.put_line('item attr: ' || DBMS_XMLDOM.GETATTRIBUTE(DBMS_XMLDOM.MAKEELEMENT(item_node), 'id', 'example:namespace'));


DBMS_XMLDOM.FREEDOCUMENT(l_domdoc);
END;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
title: "GETCHILDNODES"
---

The `GETCHILDNODES` function retrieves a `DOMNodeList` that has all the children of the particular node. If no children are there, then the `DOMNodeList` doesn't contain nodes.

```
GETCHILDNODES(n DOMNode) RETURN DOMNodeList
```

## Parameters

`n`

The `DOMNode` whose childnode list is to be retrieved.

## Examples

This example executes a function named `func1` that creates the XML structure `<Deptartments>Dept1</Deptartments>` and returns the root node which is a `DOMDocument`.

```sql
CREATE OR REPLACE FUNCTION func1 RETURN DBMS_XMLDOM.DOMNode IS
l_domdoc DBMS_XMLDOM.DOMDocument;
l_root_node DBMS_XMLDOM.DOMNode;
l_department_element DBMS_XMLDOM.DOMElement;
l_departments_node DBMS_XMLDOM.DOMNode;
l_name_text DBMS_XMLDOM.DOMText;
l_name_textnode DBMS_XMLDOM.DOMNode;
BEGIN
l_domdoc := DBMS_XMLDOM.NEWDOMDOCUMENT;
l_root_node := DBMS_XMLDOM.MAKENODE(l_domdoc);
l_department_element := DBMS_XMLDOM.CREATEELEMENT(l_domdoc, 'Departments' );
l_departments_node := DBMS_XMLDOM.APPENDCHILD(l_root_node,DBMS_XMLDOM.MAKENODE(l_department_element));
l_name_text := DBMS_XMLDOM.CREATETEXTNODE(l_domdoc, 'Dept1' );
PERFORM DBMS_XMLDOM.APPENDCHILD(l_departments_node,DBMS_XMLDOM.MAKENODE(l_name_text));
return l_root_node;
END;
```

You can retrieve all the child nodes of the root node by calling `GETCHILDNODES`, and you can determine the number of child nodes using the `GETLENGTH` function:

```sql
DECLARE
clist DBMS_XMLDOM.DOMNodeList;
len NUMBER;
BEGIN
clist := DBMS_XMLDOM.GETCHILDNODES(func1());
len := DBMS_XMLDOM.GETLENGTH(clist);
dbms_output.put_line('root node num children: ' || to_char(len));
END;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: "GETFIRSTCHILD"
---

The `GETFIRSTCHILD` function retrieves the first child of the particular node. If there is no such node, then this function returns NULL.

```
GETFIRSTCHILD(n DOMNode) RETURN DOMNode
```

## Parameters

`n`

The `DOMNode` whose first child needs to be retrieved.

## Examples

This example creates a new `DOMDocument` named `l_domdoc`, and turns it into a `DOMNode`. Then, it creates a `DOMElement` named `l_department_element` with the tag name “Departments” and appends this element as a child to the `DOMNode`. Finally, it outputs the tag name of the first (and in this example, the only) appended child.

```sql
DECLARE
l_domdoc DBMS_XMLDOM.DOMDocument;
l_root_node DBMS_XMLDOM.DOMNode;
l_department_element DBMS_XMLDOM.DOMElement;


BEGIN
l_domdoc := DBMS_XMLDOM.NEWDOMDOCUMENT();
l_root_node := DBMS_XMLDOM.MAKENODE(l_domdoc);
l_department_element := DBMS_XMLDOM.CREATEELEMENT(l_domdoc, 'Deptartments' );
PERFORM DBMS_XMLDOM.APPENDCHILD(l_root_node,DBMS_XMLDOM.MAKENODE(l_department_element));
DBMS_OUTPUT.PUT_LINE(DBMS_XMLDOM.GETNODENAME(DBMS_XMLDOM.GETFIRSTCHILD(l_root_node)));
END;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
title: "GETLENGTH"
---

The `GETLENGTH` function returns the number of nodes in a `DOMNodeList`.

```
GETLENGTH(nl DOMNodeList) RETURN PLS_INTEGER
```

## Parameters

`nl`

The `DOMNodeList`

## Examples

This example executes a function named `func1` that creates the XML structure `<Deptartments>Dept1</Deptartments>` and returns the root node which is a `DOMDocument`.

```sql
CREATE OR REPLACE FUNCTION func1 RETURN DBMS_XMLDOM.DOMNode IS
l_domdoc DBMS_XMLDOM.DOMDocument;
l_root_node DBMS_XMLDOM.DOMNode;
l_department_element DBMS_XMLDOM.DOMElement;
l_departments_node DBMS_XMLDOM.DOMNode;
l_name_text DBMS_XMLDOM.DOMText;
l_name_textnode DBMS_XMLDOM.DOMNode;
BEGIN
l_domdoc := DBMS_XMLDOM.NEWDOMDOCUMENT;
l_root_node := DBMS_XMLDOM.MAKENODE(l_domdoc);
l_department_element := DBMS_XMLDOM.CREATEELEMENT(l_domdoc, 'Deptartments' );
l_departments_node := DBMS_XMLDOM.APPENDCHILD(l_root_node,DBMS_XMLDOM.MAKENODE(l_department_element));
l_name_text := DBMS_XMLDOM.CREATETEXTNODE(l_domdoc, 'Dept1' );
PERFORM DBMS_XMLDOM.APPENDCHILD(l_departments_node,DBMS_XMLDOM.MAKENODE(l_name_text));
return l_root_node;
END;
```

You can retrieve all the child nodes of the root node by calling `GETCHILDNODES`, and you can determine the number of child nodes using the `GETLENGTH` function:

```sql
DECLARE
clist DBMS_XMLDOM.DOMNodeList;
len NUMBER;
BEGIN
clist := DBMS_XMLDOM.GETCHILDNODES(func1());
len := DBMS_XMLDOM.GETLENGTH(clist);
dbms_output.put_line('root node num children: ' || to_char(len));
END;
```
Loading

1 comment on commit e9e90c5

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.