Parsing an XML Document into Multiple Persistent Structures

This section covers an example of how an XML document is evaluated and multiple persistent structures created to contain separate sections of the document. This example takes the same file as that used in the previous section ("Parsing an XML Document into a Persistent Structure)" and creates two persistent XML documents (which are instances of WPXMLDocument), into which the details of staff for each department are separated.

JadeScript::persistentSplitImport Method

The JadeScript class persistentSplitImport method parses the XML document and creates two XML tree structures with persistent JADE objects populated from two separate sections of the XML document.

root := Root.firstInstance; 
create xmlDoc transient; 
create elmntArray transient; 
create parser transient;
parser.parseDocumentFile(xmlDoc, 
    "c:\JadeXMLWhitePaper\Persistent XML Structure.xml"); 
xmlDoc.getElementsByTagName("DEPT_PEOPLE", elmntArray); 
beginTransaction; 
foreach elmnt in elmntArray do
    name := elmnt.getAttributeByName("NAME").value; 
    create newXMLDoc persistent;

This section of the script code fragment creates the following transient instances.

  1. xmlDoc, which is passed as a parameter into the parseDocumentFile method and represents the transient XML tree structure created by the method

  2. elmntArray, which is used as a transient container for the elements that delimit the sections of the XML file in which we have an interest

  3. parser, which is used to actually parse the XML file

The specified file (that is, Persistent XML Structure.xml) is parsed as usual. The method then gets the delimiting elements from which we want to create our separate documents and then adds them to the elmntArray. As we are creating a separate document for each element in this array, the method then steps through each element and creates a persistent XML document in JADE.

A name attribute has been added to our subclass of JadeXMLDocument (that is, WPXMLDocument), to allow us to identify them for retrieval purposes. The name for each document is to be derived from the NAME attribute of the DEPT_PEOPLE element. We assign it to the name variable at this point for later use, as shown in the following code fragment.

rootElmnt := elmnt.makePersistent(WPXMLElement, WPXMLAttribute, 
    WPXMLComment, WPXMLCDATA, WPXMLText, WPXMLDocumentType, 
    WPXMLProcessingInstruction, newXMLDoc).WPXMLElement;

This code fragment takes the selected element from the array and calls the makePersistent method to, oddly enough, make it persistent.

JadeXMLNode::makePersistent Method

With the exception of newXMLDoc, which has a type of WPXMLDocument, all parameters passed into the JadeXMLNode class makePersistent method are classes. In a similar way to class mapping covered in the previous section of this appendix, it is necessary to specify what user subclasses are to be instantiated when creating a persistent copy of a transient class. It is when calling this method that those user subclasses are specified.

As we potentially need to create persistent instances of all of the different XML nodes, this method shown in the following code fragment is placed on the JadeXMLNode class.

makePersistent(elmnt, attr, comment, cdata, text, docType, pi : Class; 
    xmlDoc : JadeXMLDocument input) : JadeXMLNode updating;
vars
    newNode, newChildNode, childNode : JadeXMLNode; 
    attribute, newAttr               : JadeXMLAttribute;
begin 
    if self.isKindOf(JadeXMLElement) then
        newNode := self.makePersistentIndividual(elmnt);

This method evaluates the transient object for which it is called and calls the makePersistentIndividual method, passing the user subclass that is used to create a persistent instance.

JadeXMLNode::makePersistentIndividual Method

The JadeXMLNode class makePersistentIndividual method actually creates the persistent JADE object based on the transient object created as a result of the parsing process. When created, it is returned to the makePersistent method and assigned to the newNode variable, as shown in the following code fragment.

xmlNode := copySelfAs(class, false).JadeXMLNode; return xmlNode;

JadeXMLNode::makePersistent Method

When the new persistent XML node has been created, it is necessary to continue traversing the transient structure to ensure that the childNodes (and the childNodes of the childNodes, and so on) are processed, as shown in the following code fragment.

foreach childNode in self.childNodes do 
    newChildNode := childNode.makePersistent(elmnt, attr, comment, cdata, 
        text, docType, pi, xmlDoc);
    newChildNode.parentNode := newNode; 
endforeach;
foreach attribute in self.JadeXMLElement.attributes do
    newAttr := attribute.makePersistent(elmnt, attr, comment, cdata, 
        text, docType, pi, xmlDoc).JadeXMLAttribute;
    newAttr.setElement(newNode.JadeXMLElement); 
endforeach;
elseif self.isKindOf(JadeXMLAttribute) then 
    newNode := self.makePersistentIndividual(attr);

It is also important to note that the copySelfAs method does not copy references and that collections are empty on the copy created. As a result, the JadeXMLNode class makePersistent method then assigns values to the appropriate parentNode, document, element, and docType references.