Using PBDOM

This section describes how to accomplish basic tasks using PBDOM classes and methods. To check for complete code samples that you can download and test, select Programs>Appeon>PowerBuilder 2019 R2>Code Samples from the Windows Start menu.

Validating the XML

Before you try to build a document from a file or string, you can test whether the XML is well formed or, optionally, whether it conforms to a DTD or Schema using the XMLParseFile or XMLParseString PowerScript functions. For example, this code tests whether the XML in a file is well formed:

long ll_ret
ll_ret = XMLParseFile("c:\temp\mydoc.xml", ValNever!)

By default, these functions display a message box if errors occur. You can also provide a parsingerrors string argument to handle them yourself. For more information about these functions, see the section called “XMLParseFile” in PowerScript Reference and the section called “XMLParseString” in PowerScript Reference.

Creating an XML document from XML

The PBDOM_BUILDER class provides three methods for creating a PBDOM_DOCUMENT from an existing XML source. It also provides the GetParseErrors method to get a list of any parsing errors that occur.

Using BuildFromString

The following example uses an XML string and the PBDOM_BUILDER class to create a PBDOM_DOCUMENT. First the objects are declared:

PBDOM_BUILDER pbdom_builder_new
PBDOM_DOCUMENT pbdom_doc

The objects are then instantiated using the constructor and the PBDOM_BUILDER BuildFromString method:

pbdombuilder_new = Create PBDOM_Builder
pbdom_doc = pbdombuilder_new.BuildFromString(Xml_doc)

XML can also be loaded directly into a string variable, as in the following example:

string Xml_str
Xml_str = "<?xml version="1.0" ?>"
Xml_str += "<WHITEPAPER>"
Xml_str += "<TITLE>Document Title</TITLE>"
Xml_str += "<AUTHOR>Author Name</AUTHOR>"
Xml_str += "<PARAGRAPH>Document text.</PARAGRAPH>"
Xml_str += "</WHITEPAPER>"

Using BuildFromFile

You can create an XML file using the BuildFromFile method and a string containing the path to a file from which to create a PBDOM_DOCUMENT:

PBDOM_BUILDER     pbdombuilder_new
PBDOM_DOCUMENT     pbdom_doc
pbdombuilder_new = Create PBDOM_Builder
pbdom_doc = pbdombuilder_new.BuildFromFile &
   ("c:\pbdom_doc_1.xml")

Using BuildFromDataStore

The following PowerScript code fragment demonstrates how to use the BuildFromDataStore method with a referenced DataStore object.

PBDOM_Builder pbdom_bldr
pbdom_document pbdom_doc
datastore ds

ds = Create datastore
ds.DataObject = "d_customer"
ds.SetTransObject (SQLCA)
ds.Retrieve

pbdom_doc = pbdom_bldr.BuildFromDataStore(ds)

Using GetParseErrors

After a call to any of the Build methods, you can obtain a list of parsing and validating errors encountered by the Build methods with the GetParseErrors method:

PBDOM_Builder pbdom_bldr
pbdom_document pbdom_doc
string strParseErrors[]
BOOLEAN bRetTemp = FALSE

pbdom_buildr = Create PBDOM_BUILDER
pbdom_doc = pbdom_buildr.BuildFromFile("D:\temp.xml")
bRetTemp = pbdom_buildr.GetParseErrors(strParseErrors)
if bRetTemp = true then
   for l = 1 to UpperBound(strParseErrors)
      MessageBox ("Parse Error", strParseErrors[l])
   next
end if

Parsing errors

If parsing errors are found and GetParseErrors returns true, a complete PBDOM node tree that can be inspected might still be created.

Creating an XML document from scratch

You can create an XML document in a script using the appropriate PBDOM_OBJECT subclasses and methods. The following code uses the PBDOM_ELEMENT and PBDOM_DOCUMENT classes and some of their methods to create a simple XML document.

First, the objects are declared and instantiated:

PBDOM_ELEMENT pbdom_elem_1
PBDOM_ELEMENT pbdom_elem_2
PBDOM_ELEMENT pbdom_elem_3
PBDOM_ELEMENT pbdom_elem_root
PBDOM_DOCUMENT pbdom_doc1

pbdom_elem_1 = Create PBDOM_ELEMENT
pbdom_elem_2 = Create PBDOM_ELEMENT
pbdom_elem_3 = Create PBDOM_ELEMENT

The instantiated objects are assigned names. Note that the PBDOM_DOCUMENT object pbdom_doc1 is not named:

pbdom_elem_1.SetName("pbdom_elem_1")
pbdom_elem_2.SetName("pbdom_elem_2")
pbdom_elem_3.SetName("pbdom_elem_3")

The objects are arranged into a node tree using the AddContent method. The AddContent method adds the referenced object as a child node under the object from which AddContent is invoked:

pbdom_elem_1.AddContent(pbdom_elem_2)
pbdom_elem_2.AddContent(pbdom_elem_3)

Use the NewDocument method to create a new XML document. The parameter value supplied to the NewDocument method becomes the name of the root element. This name is then accessed from the PBDOM_DOCUMENT object pbdom_doc1 and assigned to the PBDOM_ELEMENT object pbdom_elem_root using the GetRootElement method:

pbdom_doc1.NewDocument("Root_Element_From_Doc_1")
pbdom_elem_root = pbdom_doc1.GetRootElement()

The ELEMENT object pbdom_elem_1 and all its child nodes are placed in the new XML document node tree under the root element using the AddContent method. Note that as the ancestor node pbdom_elem_1 is placed in the node tree, all its child nodes move as well:

pbdom_elem_root.AddContent(pbdom_elem_1)

The XML document created looks like this:

<!DOCTYPE Root_Element_From_Doc_1> 
<Root_Element_From_Doc_1>
    <pbdom_elem_1>
        <pbdom_elem_2>
            <pbdom_elem_3/> 
        </pbdom_elem_2>
    </pbdom_elem_1>
</Root_Element_From_Doc_1>

Accessing node data

An XML document can be read by accessing the elements of its node tree using the appropriate PBDOM_OBJECT subclasses and methods. The following code uses an array, the PBDOM_OBJECT, and its descendant class PBDOM_DOCUMENT, and the GetContent and GetRootElement methods of the PBDOM_DOCUMENT class to access node data on an XML document.

A PBDOM_DOCUMENT object named pbdom_doc contains the following XML document:

<Root>
    <Element_1>
        <Element_1_1/>
        <Element_1_2/>
        <Element_1_3/>
    </Element_1>
    <Element_2/>
    <Element_3/>
</Root>

The following code declares an array to hold the elements returned from the GetContent method, which reads the PBDOM_DOCUMENT object named pbdom_doc:

PBDOM_OBJECT pbdom_obj_array[]
...
pbdom_doc.GetContent(ref pbdom_obj_array)

The pbdom_obj_array array now contains one value representing the root element of pbdom_doc: <Root>.

To access the other nodes in pbdom_doc, the GetRootElement method is used with the GetContent method.

pbdom_doc.GetRootElement().GetContent &
   (ref pbdom_obj_array)

The pbdom_obj_array array now contains three values corresponding to the three child nodes of the root element of pbdom_doc: <Element_1>, <Element_2>, and <Element_3>.

PBDOM provides other methods for accessing data, including InsertContent, AddContent, RemoveContent, and SetContent.

Changing node content with arrays

You can use the AddContent method to change node content:

pbdom_obj_array[3].AddContent("This is Element 3.")

This line of code changes the node tree as follows:

<Root>
    <Element_1>
        <Element_1_1/>
        <Element_1_2/>
        <Element_1_3/>
    </Element_1>
    <Element_2/>
    <Element_3>This is Element 3.</Element_3>
</Root>

Arrays and object references

When you use a method such as the GetContent method of the PBDOM_DOCUMENT class to return an array of PBDOM_OBJECT references, the references are to instantiated PBDOM objects. If you modify any of these objects through its array item, the changes are permanent and are reflected in any other arrays that hold the same object reference.

Manipulating the node-tree hierarchy

You can restructure an XML node tree by rearranging its nodes. One means of manipulating nodes involves detaching a child node from its parent node. This can be accomplished with the Detach method, as in the following example.

The root element of a PBDOM_DOCUMENT object named pbdom_doc is obtained using the GetRootElement method:

pbdom_obj = pbdom_doc.GetRootElement()

The root element is detached from the PBDOM_DOCUMENT object, which is the parent node of the root element:

pbdom_obj.Detach()

PBDOM provides the SetParentObject method to make an object a child of another object.

Checking for parent node

The GetParentObject method can be used to determine whether an element has a parent object, as in the following example:

pbdom_parent_obj = pbdom_obj.GetParentObject()
if not IsValid(pbdom_parent_obj) then
   MessageBox ("Invalid", "Root Element has no Parent")
end if

If the object on which GetParentObject is called has no parent object, the function returns NULL.

PBDOM provides similar methods that return information about an element's place in an XML node tree. These methods include HasChildren, which returns a boolean indicating whether an object has child objects, and IsAncestorObjectOf, which indicates whether an object is the ancestor of another object.