How to traverse xml doc and update attribute (using classes

Posted by Rom Elwell on 09-Aug-2011 11:30

Good day,

Setup:

Business logic requires that once a dataset-handle is pointing to valid data, the software evaluates the contents of the data, and if necessary, as mandated by the data values in the dataset, programmatically update the xml schema (xsd) associated with the dataset.  In the code below, we are looking for the xml element 'empid' (please note this element is hardcoded strictly for testing purposes and will be replaced by a variable once the process is functioning as desired). Once this element is found, we want to update the element by adding the attribute INITIAL='LOCKED' and then save the modified output so that the xml schema for the bound dataset is updated before passing the handle to the .NET client for display to the user.

Issue:

I can traverse the xml file correctly, even finding the element in question.  However, after I update the attribute for the target element, and return execution back to the main block, the xml-schema for the handle to the dataset is unmodified.  How can I transverse an xml schema associated to a dataset and modify attributes for specific elements within the xml-schema document?

For example:

ORIGINAL XML ELEMENT:

<xsd:element name="empid" type="xsd:string" nillable="true" prodata:format="x(12)" prodata:label="ID" prodata:columnLabel="&amp;ID"/>

MODIFIED XML ELEMENT:

<xsd:element name="empid" type="xsd:string" nillable="true" default="LOCKED" prodata:format="x(12)" prodata:label="ID" prodata:columnLabel="&amp;ID"/>

The sequence, in code, is as follows:

        /* MAIN EXECUTION */

CREATE VARIABLE mXMLHdl AS HANDLE NO-UNDO.

CREATE VARIABLE mXMLDoc AS HANDLE NO-UNDO.

/* reference returned data using dsOutputHdl */

RequestEntity( INPUT DATASET-HANDLE dsInputHdl BY-REFERENCE, OUTPUT DATASET-HANDLE dsOutputHdl BY-REFERENCE ).

/* create handle to xml-schema associated with dsOutputHdl and pass document element to recursive method to find element 'empid' */

CREATE X-DOCUMENT mXMLHdl.

CREATE X-NODEREF mXMLDoc.

dsOutputHdl:WRITE-XMLSCHEMA ("HANDLE", mXMLHdl, TRUE, 'UTF-8', FALSE, FALSE) NO-ERROR.

dsOutputHdl:GET-DOCUMENT-ELEMENT(mXMLDoc).

oXMLRequest:FindElement(INPUT-OUTPUT mXMLDoc, 'empid').

/* at this point, the xml-schema is unexpectedly unmodified.  It should have the additional attribute added in FindeElement method */

****

METHOD PUBLIC LOGICAL FindElement (INPUT-OUTPUT xNode AS HANDLE, INPUT eleName AS CHARACTER):      

    DEFINE VARIABLE hParent AS HANDLE NO-UNDO.

    DEFINE VARIABLE hChild AS HANDLE NO-UNDO.

    DEFINE VARIABLE iter      AS INT    NO-UNDO.

    DEFINE VARIABLE isFound AS LOGICAL INIT NO NO-UNDO.

    CREATE X-DOCUMENT hParent.

    CREATE X-NODEREF  hChild.

    /* Process the node here */

    IF xNode:GET-ATTRIBUTE('name') EQ eleName THEN DO:

      /* empid */

      xNode:SET-ATTRIBUTE ('default','LOCKED').

      isFound = YES.

    /* if I call write-xml on the xNode object, the attribute 'default' has the value of 'LOCKED', as expected. */

    END.

    /* parent is not the desired element, so, begin querying children elements with a recursive call */

    IF isFound = NO THEN DO:

        DO iter = 1 TO xNode:NUM-CHILDREN:

            xNode:GET-CHILD(hChild,iter).

            isFound = THIS-OBJECT:FindElement(INPUT-OUTPUT hChild,eleName).

            IF isFound THEN

                /* found the element so assume the xml-schema is modified at this point and leave the DO iter loop */

                LEAVE.

        END.

    END.

    DELETE OBJECT hChild.

    DELETE OBJECT hParent.

    RETURN isFound.

END METHOD.

All Replies

Posted by Thomas Mercer-Hursh on 09-Aug-2011 12:12

You might find this easier to do using SAX.

Posted by gus on 09-Aug-2011 13:04

Looks to me like you are writing before modifying.

dsOutputHdl:WRITE-XMLSCHEMA ("HANDLE", mXMLHdl, TRUE, 'UTF-8', FALSE, FALSE) NO-ERROR.

dsOutputHdl:GET-DOCUMENT-ELEMENT(mXMLDoc).

oXMLRequest:FindElement(INPUT-OUTPUT mXMLDoc, 'empid').

This thread is closed