Module Flexml.pkg

     1//****************************************************************************************
     2//                                                                                       *
     3//  FLEXML.PKG                                                                            *
     4//                                                                                       *
     5//  Interface package for FLEXML.DLL - extension system for Extensible Markup Language.  *
     6//                                                                                       *
     7//  Written by Michael Gouker, 7/31/99                                                   *
     8// 12/19/2000 JJT - Major revision changes for VDF7/SP2.                                 *
     9//                                                                                       *
    10//****************************************************************************************
    11Use LanguageText.pkg
    12Use Windows.pkg
    13Use GlobalFunctionsProcedures.pkg
    14
    15// Used to designate that a handle is a handle to an Xml Dom object. This
    16// is used/required by server web-services but could be used elsewhere .
    17#Replace xmlHandle Handle
    18
    19
    20// Types of Nodes
    21
    22#Replace  NODE_ELEMENT                1
    23#Replace  NODE_ATTRIBUTE              2
    24#Replace  NODE_TEXT                   3
    25#Replace  NODE_CDATA_SECTION          4
    26#Replace  NODE_ENTITY_REFERENCE       5
    27#Replace  NODE_ENTITY                 6
    28#Replace  NODE_PROCESSING_INSTRUCTION 7
    29#Replace  NODE_COMMENT                8
    30#Replace  NODE_DOCUMENT               9
    31#Replace  NODE_DOCUMENT_TYPE         10
    32#Replace  NODE_DOCUMENT_FRAGMENT     11
    33#Replace  NODE_NOTATION              12
    34
    35// classes and methods defined in fmac
    36
    37
    38Register_Function transformNode Integer infcXSLNode Returns String
    39
    40
    41#Replace DF_IXMLINTERNAL                 0
    42#Replace DF_IXMLDOMNODE                  1
    43#Replace DF_IXMLDOMNODELIST              2
    44#Replace DF_IXMLDOMNAMEDNODEMAP          3
    45#Replace DF_IXMLPARSEERROR               4
    46#Replace DF_IXMLDOMDOCUMENTFRAGMENT      5
    47#Replace DF_IXMLDOMDOCUMENT              6
    48#Replace DF_IXMLDOMCHARACTERDATA         7
    49#Replace DF_IXMLDOMTEXT                  8
    50#Replace DF_IXMLDOMCDATASECTION          9
    51#Replace DF_IXMLDOMCOMMENT               10
    52#Replace DF_IXMLDOMATTRIBUTE             11
    53#Replace DF_IXMLDOMELEMENT               12
    54#Replace DF_IXMLDOMPROCESSINGINSTRUCTION 13
    55#Replace DF_IXMLDOMDOCUMENTTYPE          14
    56#Replace DF_IXMLDOMNOTATION              15
    57#Replace DF_IXMLDOMENTITY                16
    58#Replace DF_IXMLDOMENTITYREFERENCE       17
    59#Replace DF_IXMLDOMIMPLEMENTATION        18
    60
    61
    62
    63
    64#Replace FLEXML_STRING        1
    65#Replace FLEXML_BOOLEAN       2
    66#Replace FLEXML_UCHAR         3
    67#Replace FLEXML_CHAR          4
    68#Replace FLEXML_USHORT        5
    69#Replace FLEXML_SHORT         6
    70#Replace FLEXML_UINTEGER      7
    71#Replace FLEXML_INTEGER       8
    72#Replace FLEXML_UBIGINT       9
    73#Replace FLEXML_BIGINT        10
    74#Replace FLEXML_FLOAT         11
    75#Replace FLEXML_DOUBLE        12
    76#Replace FLEXML_DATE          13
    77#Replace FLEXML_TIME          14
    78#Replace FLEXML_NUMBER        15
    79#Replace FLEXML_BINARY        16
    80
    81#Replace FLEXML_COINITIALIZE                     0
    82#Replace FLEXML_COUNINITIALIZE                   1
    83#Replace CREATE_XML_INTERFACE                    2
    84#Replace DESTROY_XML_INTERFACE                   3
    85#Replace FLEXML_GETVERSION                       4
    86#Replace FLEXML_GETBUILD                         5
    87
    88
    89// XML function & procedure registration
    90
    91Register_Procedure Set XmlInterface Integer iHandle
    92Register_Function XmlInterface Returns Integer
    93
    94// NODE Properties
    95Register_Function phAttributes Returns Integer
    96Register_Function psBaseName Returns String
    97Register_Function phChildNodes Returns Integer
    98Register_Function phDefinition Returns Integer
    99Register_Function phFirstChild Returns Integer
   100Register_Function phLastChild Returns Integer
   101Register_Function phNextSibling Returns Integer
   102Register_Function psNameSpaceURI Returns String
   103Register_Function psNodeName Returns String
   104Register_Function piNodeType Returns Integer
   105Register_Function psNodeTypeString Returns String
   106Register_Function phOwnerDocument Returns Integer
   107Register_Function phParentNode Returns Integer
   108Register_Function pbParsed Returns Integer
   109Register_Function psPrefix Returns String
   110Register_Function phPreviousSibling Returns Integer
   111Register_Function pbSpecified Returns Integer
   112Register_Function psText Returns String
   113Register_Procedure Set psText String sText
   114Register_Function psXML Returns String
   115
   116// Node Read write properties
   117
   118Register_Procedure Set psDataType String sTypeName
   119Register_Function psDataType Returns String
   120Register_Procedure Set pvNodeTypedValue Integer iType Integer iAddress
   121Register_Function pvNodeTypedValue Integer iType Returns Integer  // address of data
   122Register_Procedure Set psNodeValue String sValue
   123Register_Function psNodeValue Returns String
   124
   125// Node Methods
   126
   127Register_Function AppendChild Integer iChildInfc Returns Integer
   128Register_Function CloneInfcNode Integer bRecurse Returns Integer
   129Register_Function HasChildNodes Returns Integer
   130Register_Function InsertBefore Integer infcNodeToInsert Integer iWhere Returns Integer
   131Register_Function RemoveChild Integer iChildToRemove Returns Integer
   132Register_Function ReplaceChild Integer iNewChild Integer iChildToReplace Returns Integer
   133Register_Function SelectNodes String selectstring Returns Integer
   134Register_Function SelectSingleNode String selectstring Returns Integer
   135
   136// Node Collections
   137// READONLY PROPERTIES
   138
   139Register_Function phItem Integer iItem Returns Integer
   140Register_Function phElementItem Integer iItem Returns Integer
   141
   142Register_Function piLength Returns Integer
   143
   144//*     GET_ENUMNODELIST                  */  typ_p1_int | qt_int | out_two,
   145//*     GET_RESET                         */  qt_int | out_one,
   146
   147// Named Node Map
   148
   149//*     GET_NAMEDITEM                     */  typ_p1_str | qt_int | out_two,
   150
   151Register_Function NamedItem String sName Returns Integer
   152Register_Function QualifiedItem String sBaseName String sNameSpace Returns Integer
   153Register_Function RemoveNamedItem String sName Returns Integer
   154Register_Function RemoveQualifiedItem String sBaseName String sNameSpace Returns Integer
   155Register_Function SetNamedItem Integer iInterface Returns Integer
   156
   157// XML DOM Document
   158// Read only properties
   159
   160Register_Function phDocType Returns Integer
   161Register_Function phImplementation Returns Integer
   162Register_Function phParseError Returns Integer
   163Register_Function piReadyState Returns Integer
   164Register_Function psURL Returns String
   165
   166// Read Write Properties
   167
   168Register_Procedure Set pbAsync Integer bValue
   169Register_Function pbAsync Returns Integer
   170Register_Procedure Set phDocumentElement Integer iElement
   171Register_Function phDocumentElement Returns Integer
   172Register_Procedure Set pbPreserveWhiteSpace Integer bValue
   173Register_Function pbPreserveWhiteSpace Returns Integer
   174Register_Procedure Set pbResolveExternals Integer bValue
   175Register_Function pbResolveExternals Returns Integer
   176Register_Procedure Set pbValidateOnParse Integer bValue
   177Register_Function pbValidateOnParse Returns Integer
   178
   179// Events
   180
   181// Methods
   182
   183Register_Function Abort Returns Integer
   184Register_Function ElementsByTagName String sTagName Returns Integer
   185Register_Function LoadDocument String sURLName Returns Integer
   186Register_Function LoadXML String sXMLText Returns Integer
   187Register_Function NodeFromID String sNodeName Returns Integer
   188Register_Function SaveDocument String sURLName Returns Integer
   189
   190// Parse Error
   191// Read Only Properties
   192
   193Register_Function piErrorCode Returns Integer
   194Register_Function piFilePos Returns Integer
   195Register_Function piLine Returns Integer
   196Register_Function piLinePos Returns Integer
   197Register_Function psReason Returns String
   198Register_Function psSrcText Returns String
   199Register_Function psURL Returns String
   200
   201// DOM Implementation
   202// Method
   203
   204Register_Function HasFeature String sSystem String sFeature Returns Integer
   205
   206// Methods
   207
   208Register_Function substringData Integer iOffset Integer iCount Returns String
   209Register_Function appendData String sData Returns Integer
   210Register_Function insertData Integer iOffset String sData Returns Integer
   211Register_Function deleteData Integer iOffset Integer iCount Returns Integer
   212Register_Function replaceData Integer iOffset Integer iCount String sData Returns Integer
   213
   214// Attributes
   215
   216Register_Function psName Returns String
   217
   218// Elements
   219// Read Only properties
   220
   221Register_Function psTagName Returns String
   222
   223// Methods
   224
   225Register_Procedure Set attributeValue String sName String sValue
   226Register_Function attributeValue String sName Returns String
   227Register_Function removeAttribute String sName Returns Integer
   228Register_Function attributeNode String sName Returns Integer
   229Register_Procedure Set attributeNode Integer iNode Returns Integer
   230Register_Function removeAttributeNode Integer iNode Returns Integer
   231
   232// DOM Text
   233// Methods
   234
   235Register_Function splitText Integer iOffset Returns Integer
   236
   237// DOM Processing Instruction
   238// Read Only Properties
   239Register_Function psTarget Returns String
   240
   241// DOM Document Type
   242
   243Register_Function phEntities Returns Integer
   244Register_Function phNotations Returns Integer
   245
   246// DOM Notations
   247
   248Register_Function psPublicID Returns String
   249Register_Function psSystemID Returns String
   250Register_Function psNotationName Returns String
   251
   252// create nodes
   253
   254Register_Function createAttribute String sName Returns Integer
   255Register_Function createCDataSection String sValue Returns Integer
   256Register_Function createComment String sValue Returns Integer
   257Register_Function createDocumentFragment Returns Integer
   258Register_Function createElement String sTagName Returns Integer
   259Register_Function createEntityReference String sEntityName Returns Integer
   260Register_Function createNode Integer iNodeType String sName String sNameSpace Returns Integer
   261Register_Function createProcessingInstruction String sTarget String sData Returns Integer
   262Register_Function createTextNode String sData Returns Integer
   263
   264Register_Function ChangeNodeType Integer iTypeOfNode Integer bSetInterface Returns Integer
   265
   266
   267// ******************************************************************************
   268//
   269//          Part 1:  Base Document Logic Specialized For Templates
   270//
   271// ******************************************************************************
   272
   273//
   274//  XML Collections
   275//
   276//  Collection mixin has common functions to both node lists and named node maps
   277//
   278
   279// This provides functions required of all XMLDOM objects.
   280//
   281{ ClassLibrary=Common }
   282Class cXMLDOMMixin is a Mixin
   283
   284    // Create an XML object of passed class Id and bind passed interface. returns
   285    // the object handle. All dynamic XML object can be created using this syntax
   286
   287    { Visibility=Private }
   288    Function CreateXMLObject Integer iClassId Integer hinfXMLInterface Returns Handle
   289        Handle hoId hoDocument
   290        // We will always create objects at the DOMDocument level.
   291        Get DocumentObject to hoDocument
   292        If (hoDocument=0) Begin  // this should never happen.
   293            Error DFERR_XML_INTERNAL_ERROR C_$XmlFailedNoDocObject
   294            Function_Return 0
   295        End
   296        If hinfXMLInterface Begin
   297            Get Create of hoDocument iClassId to hoID
   298            Set XMLInterface of hoID to hinfXMLInterface
   299        End
   300        Function_Return hoID
   301    End_Function
   302
   303    // create an XML Node object based on the interface type.
   304    // this will convert the interface to the proper type and will create
   305    // an appropriate DF object.
   306    // This requires that a DocumentObject exists
   307
   308    { Visibility=Private }
   309    Function CreateXMLNode Handle hinfc Returns Handle
   310        Integer hoNode iType iClassId
   311        Handle  hoDocument
   312        // Get the node type of the infc handle w/o creating a DF object
   313        Move (invokexml(DF_IXMLDOMNODE, GET_piNodeType, hinfc, 0, 0, 0, 0)) to iType
   314        Move (invokexml(DF_IXMLDOMNODE, GET_ChangeNodeType, hinfc, iType, 1, 0, 0)) to hInfc
   315        If (hinfc=0) Begin
   316            // this should not happen and we would need to know about this.
   317            Error DFERR_XML_INTERNAL_ERROR (C_$XmlFailedNoDocObject + String(iType))
   318            Function_Return 0
   319        End
   320        Get DocumentObject to hoDocument
   321        // you can augment your class IDs in a single place.
   322        Get NodeClassId of hoDocument iType to iClassId
   323        // MG: 12/6/00 Changed to create nodes inside of the document object.
   324        Get CreateXMLObject of hoDocument iClassId hinfc to hoNode
   325
   326        Function_Return hoNode
   327    End_Function
   328
   329
   330    // Change object's class. This let's you change the class id of an object
   331    // on an object by object basis. This would let you create nodes (e.g. elements)
   332    // that have a custom interface for each node type. Normally, this would be sent
   333    // after a node has been created using one of the default classes
   334    Function ChangeNodeClass Integer hoNode Integer iClassID Returns Handle
   335        Integer iType
   336        Handle  hinfcNew
   337        Get piNodeType of hoNode to iType
   338        Get ChangeNodeType of hoNode iType False to hInfcNew
   339        Send Destroy to hoNode // destroy object and old infc handle.
   340        Get CreateXMLObject iClassId hinfcNew to hoNode
   341        Function_Return hoNode
   342    End_Function
   343
   344End_Class
   345
   346
   347{ ClassLibrary=Common }
   348Class cXMLDOMCollectionMixin is a Mixin
   349
   350    Import_Class_Protocol cXMLDOMMixin
   351
   352    //  Returns number of items in the collection
   353    //
   354    Function NodeListLength Returns Integer
   355        Integer iLength
   356        Get piLength to iLength
   357        Function_Return iLength
   358    End_Function
   359
   360    // Returns an XML node object for pass item
   361    //
   362    Function CollectionNode Integer I Returns Handle
   363        Integer hoNewNode
   364        Integer infcItem
   365        Get phItem i to infcItem
   366        If (infcItem) ;
   367            Get CreateXMLNode infcItem to hoNewNode
   368        Function_Return hoNewNode
   369    End_Function
   370
   371
   372End_Class
   373
   374// Simple declarations of collections.
   375
   376{ ClassLibrary=Common }
   377{ HelpTopic=cXMLDOMNodeList }
   378Class cXMLDOMNodeList is a BaseXmlDomNodeList
   379    Import_Class_Protocol cXMLDOMCollectionMixin
   380End_Class
   381
   382{ ClassLibrary=Common }
   383{ HelpTopic=cXMLDOMNamedNodeMap }
   384Class cXMLDOMNamedNodeMap is a BaseXmlDomNamedNodeMap
   385
   386    Import_Class_Protocol cXMLDOMCollectionMixin
   387
   388    // returns a node attribute that matches passed name, zero if none
   389    Function NamedNode String sName Returns Handle
   390        Integer hoNewNode
   391        Integer infcItem
   392        Get NamedItem sName to infcItem
   393        If infcItem ;
   394            Get CreateXMLNode infcItem to hoNewNode
   395        Function_Return hoNewNode
   396    End_Function
   397
   398    // Adds or changes a node attribute
   399    // This should return the passed object Id which is now bound to the attribute. If an error, returns 0
   400    Function SetNamedNode Handle hoNode Returns Handle
   401        Integer hinfcNode hinfcItem
   402        Get XMLInterface of hoNode to hinfcNode // node of passed attribute
   403        Get SetNamedItem hinfcNode to hinfcItem
   404        If hinfcItem ;
   405            Set XMLInterface of hoNode to hinfcItem
   406        Else ;
   407            Move 0 to hoNode // zero indicates error
   408        Function_Return hoNode
   409    End_Function
   410
   411    // removes named attribute, Returns handle of removed node or zero if not found.
   412    // Note that returned object must be disposed of or moved somewhere else.
   413    Function RemoveNamedNode String sName Returns Handle
   414        Integer hoNewNode
   415        Integer infcItem
   416        Get RemoveNamedItem sName to infcItem
   417        If infcItem ;
   418            Get CreateXMLNode infcItem to hoNewNode
   419        Function_Return hoNewNode
   420    End_Function
   421
   422    Function QualifiedNode String sNameSpace String sBaseName Returns Handle
   423        Integer hoNewNode
   424        Integer infcItem
   425        Get QualifiedItem  sBaseName sNameSpace  to infcItem
   426        If infcItem ;
   427            Get CreateXMLNode infcItem to hoNewNode
   428        Function_Return hoNewNode
   429    End_Function
   430
   431    Function RemoveQualifiedNode String sNameSpace String sBaseName Returns Handle
   432        Integer hoNewNode
   433        Integer infcItem
   434        Get RemoveQualifiedItem sBaseName sNameSpace to infcItem
   435        If infcItem ;
   436            Get CreateXMLNode infcItem to hoNewNode
   437        Function_Return hoNewNode
   438    End_Function
   439
   440End_Class
   441
   442
   443
   444// Mixin for nodes.
   445//
   446//  First the declaration of functions that have no object references.
   447//
   448
   449
   450{ ClassLibrary=Common }
   451Class cXMLDOMNodeMixin is a Mixin
   452
   453    Import_Class_Protocol cXMLDOMMixin
   454
   455    //  Append Node to the end of list. Returns passed Object handle if Ok, 0 if error
   456
   457    Function AppendNode Handle hoNode Returns Handle
   458        Integer hoNewTextNode
   459        Integer hinfcNode
   460        Integer infcReturned
   461        // Get COM Interface to call Append child.
   462        Get XMLInterface of hoNode to hinfcNode
   463        If (hinfcNode=0) Function_Return 0
   464        Get AppendChild hinfcNode to infcReturned
   465        // Interface returned is stored in DataFlex object.
   466        If (infcReturned=0) Function_Return 0
   467        Set XMLInterface of hoNode to infcReturned
   468        Function_Return hoNode
   469    End_Function
   470
   471    //  Insert NewNode before Node. Returns passed newnode Object handle if Ok, 0 if error
   472
   473    Function InsertBeforeNode Integer hoNewNode Integer hoNode Returns Handle
   474        Integer hinfcNewNode hinfcNode iType hoRefNode
   475        Integer infcReturned
   476        // DOM says if no refnode argument passed or it is 0, append to end
   477        If (Num_Arguments=1) ;
   478            Move 0 to hoRefNode
   479        Else ;
   480            Move hoNode to hoRefNode
   481        Get XMLInterface of hoNewNode to hinfcNewNode
   482        If (hinfcNewNode=0) Function_Return 0
   483        If hoRefNode Begin
   484            Get XMLInterface of hoRefNode to hinfcNode
   485            If (hinfcNode=0) Function_Return 0
   486        End
   487        Get InsertBefore hinfcNewNode hinfcNode to infcReturned
   488        If (infcReturned=0) Function_Return 0
   489        // Interface returned is stored in DataFlex object.
   490        Set XMLInterface of hoNewNode to infcReturned
   491        Function_Return hoNewNode
   492    End_Function
   493
   494    //  Remove Node. Returns object Id of removed node, zero if error
   495    //  Important: The node is not destroyed! This lets you move it elsewhere if you want
   496
   497    Function RemoveNode Integer hoNode Returns Handle
   498        Integer hInfcNode
   499        Get XMLInterface of hoNode to hInfcNode
   500        If (hinfcNode=0) Function_Return 0
   501        Get RemoveChild hInfcNode to hinfcNode
   502        If (hinfcNode=0) Function_Return 0
   503        Set XMLInterface of hoNode to hinfcNode
   504        Function_Return hoNode
   505    End_Function
   506
   507    //  Replace Node. Returns object Id of replaced node, zero if error
   508    //  Important: The replaced node is not destroyed! This lets you move it elsewhere if you want
   509
   510    Function ReplaceNode Integer hoNewNode Integer hoNodeToReplace Returns Handle
   511        Integer hInfcNewNode hinfcNodetoReplace hinfcNode
   512        Get XMLInterface of hoNewNode       to hInfcNewNode
   513        Get XMLInterface of hoNodetoReplace to hInfcNodetoreplace
   514        If (hinfcNewNode=0 or hInfcNodeToReplace=0) Function_Return 0
   515        Get ReplaceChild hInfcNewNode hinfcNodeToReplace to hinfcNode
   516        If (hinfcNode=0) Function_Return 0
   517        Set XMLInterface of hoNodetoReplace to hinfcNode
   518        Function_Return hoNodetoReplace
   519    End_Function
   520
   521    // Remove the named node. Returns handle to removed node. You must destroy
   522    // or move this removed object as needed
   523
   524    Function RemoveNamedNode String sQueryString Returns Handle
   525        Integer hoNode
   526        Integer hInfcTemplate hinfcNode
   527        Get SelectSingleNode sQueryString to hinfcTemplate
   528        If (hinfcTemplate) Begin
   529            // Remove child returns an interface to the disassociated node.
   530            // It should be disposed by setting it to an object and then calling destroy
   531            Get RemoveChild hInfcTemplate to hInfcNode
   532            If hInfcNode Get CreateXMLNode hinfcNode to hoNode
   533        End
   534        Function_Return hoNode
   535    End_Function
   536
   537    // This function creates a clone of the passed Node. if bRecurse all child nodes are also
   538    // cloned. The object Id of the new clone object is returned.
   539    // The interface of the object returned can be used in AppendChild to add
   540    // the node to the XML Document.
   541
   542    Function CloneNode Integer bRecurse Returns Handle
   543        Handle hoNewNode
   544        Handle hinfcNewNode
   545        Get CloneInfcNode (If(bRecurse,-1,0)) to hinfcNewNode
   546        If hinfcNewNode ;
   547            Get CreateXMLNode hinfcNewNode to hoNewNode
   548        Function_Return hoNewNode
   549    End_Function
   550
   551    //  Create a collection of all nodes. returns handle of a cXMLDomNodeList
   552
   553    Function ChildNodes Returns Handle
   554        Integer infcNodeList
   555        Integer hoNodeList
   556        Get phChildNodes to infcNodeList
   557        If (infcNodeList) ;
   558            Get CreateXMLObject U_cXMLDOMNodeList infcNodeList to hoNodeList
   559        Function_Return hoNodeList
   560    End_Function
   561
   562    //  Create a collection of all attributes. returns handle of a cXMLDomNodeMapList
   563
   564    Function AttributeNodes Returns Handle
   565        Integer hoCollectionId   // Object to hold collection
   566        Integer hinfcAttributes  // XML Interface for collection
   567        Get phAttributes to hinfcAttributes
   568        If (hinfcAttributes) ;
   569            Get CreateXMLObject U_cXMLDOMNamedNodeMap hinfcAttributes to hoCollectionId
   570        Function_Return hoCollectionId
   571    End_Function
   572    
   573    //  Create a collection of all attributes for the temporary attribute node object.
   574    //  Using this saves a small amount of time creating and destroying this object but
   575    //  it must be used with care. This binding is temporary!
   576    { Visibility=Private }
   577    Function TempAttributeNodes Returns Handle
   578        Handle hoCollectionId hoDocument
   579        Handle hinfcAttributes  // XML Interface for collection
   580        Get phAttributes to hinfcAttributes
   581        If (hinfcAttributes) Begin
   582            Get DocumentObject to hoDocument
   583            Get phoTempDomNodeMap of hoDocument to hoCollectionId
   584            Set XMLInterface of hoCollectionId to hinfcAttributes
   585        End
   586        Function_Return hoCollectionId
   587    End_Function
   588    
   589
   590    // Returns a collection of just elements
   591
   592    Function ElementNodes String sQueryString Returns Handle
   593        Integer hoNodeList
   594        Integer hinfcNodeList
   595        Get ElementsByTagName sQueryString to hinfcNodeList
   596        If (hinfcNodeList <> 0) ;
   597            Get CreateXMLObject U_cXMLDOMNodeList hinfcNodeList to hoNodeList
   598        Function_Return hoNodeList
   599    End_Function
   600
   601
   602
   603    // Return object handle for query.
   604
   605    Function FindNode String sQueryString Returns Handle
   606        Integer hoNode
   607        Integer hinfcNode
   608        Get SelectSingleNode sQueryString to hinfcNode
   609        //inkey windowindex
   610        If (hinfcNode <> 0) ;
   611            Get CreateXMLNode hInfcNode to hoNode
   612        Function_Return hoNode
   613    End_Function
   614
   615    // Return object handle for a collection node.
   616
   617
   618    Function FindNodeList String sQueryString Returns Handle
   619        Integer hoNodeList
   620        Integer hinfcNodeList
   621        Get SelectNodes sQueryString to hinfcNodeList
   622        If (hinfcNodeList <> 0) ;
   623            Get CreateXMLObject U_cXMLDOMNodeList hinfcNodeList to hoNodeList
   624        Function_Return hoNodeList
   625    End_Function
   626
   627    // The CreatexxxxxNode messages creates an node object for the type specified. Both
   628    // the interface and the object or of the correct type (i.e. element, comment)
   629    // These all return an object handle which can be used to place the object via
   630    // appendNode or InsertBeforeNode
   631
   632    // This function creates a child element, returning a dataflex object.
   633    // The interface of the object returned can be used in AppendChild to add
   634    // the element to the XML Document.
   635
   636    Function CreateElementNode String sTagName String sValue Returns Handle
   637        Integer hoNewElement
   638        Integer hoDocumentObject
   639        Integer infcNewElement
   640        Integer iClassId
   641        // The DataFlex objects are created inside the nodes (elements).
   642        // Create an element in the document and assign its interface to the new DF object.
   643        Get DocumentObject to hoDocumentObject
   644        Get createElement of hoDocumentObject sTagName to infcNewElement
   645        If infcNewElement Begin // if there was an error, no infc handle would be returned
   646            Get NodeClassId of hoDocumentObject NODE_ELEMENT to iClassId
   647            Get CreateXMLObject iClassId infcNewElement to hoNewElement
   648            If hoNewElement ; // very unlikely this will be zero
   649                Set psText of hoNewElement to sValue
   650        End
   651        Function_Return hoNewElement
   652    End_Function
   653
   654    // This function creates an attribute in a document. Attributes are _NOT_ children of an element.
   655    // A DataFlex object is returned. An attribute can be added to an xml document using
   656    // get AddAttributeNode.
   657
   658    Function CreateAttributeNode String sName String sValue Returns Handle
   659        Integer hoNewAttribute
   660        Integer hoDocumentObject
   661        Integer infcNewAttribute
   662        Integer iClassId
   663        Get DocumentObject to hoDocumentObject
   664        // Create an Attribute in the document and assign its interface to the new DF object.
   665        Get createAttribute of hoDocumentObject sName to infcNewAttribute
   666        If infcNewAttribute Begin // if there was an error, no infc handle would be returned
   667            Get NodeClassId of hoDocumentObject NODE_ATTRIBUTE to iClassId
   668            Get CreateXMLObject iClassId infcNewAttribute to hoNewAttribute
   669            // Set the value of the attribute.
   670            If hoNewAttribute ; // very unlikely this will be 0
   671                Set psText of hoNewAttribute to sValue
   672        End
   673        Function_Return hoNewAttribute
   674    End_Function
   675
   676    // This function creates a child comment, returning a dataflex object.
   677    // The interface of the object returned can be used in AppendChild to add
   678    // the comment to the XML Document.
   679
   680    Function CreateChildComment String sValue Returns Handle
   681        Integer hoNewComment
   682        Integer hoDocumentObject
   683        Integer infcNewComment
   684        Integer iClassID
   685        Get DocumentObject to hoDocumentObject
   686        // Create an Comment in the document and assign its interface to the new DF object.
   687        Get createComment of hoDocumentObject sValue to infcNewComment
   688        If infcNewComment Begin // if there was an error, no infc handle would be returned
   689            Get NodeClassId of hoDocumentObject NODE_COMMENT to iClassId
   690            Get CreateXMLObject iClassId infcNewComment to hoNewComment
   691            If hoNewComment ; // very unlikely this will be 0
   692                Set psText of hoNewComment to sValue
   693        End
   694        Function_Return hoNewComment
   695    End_Function
   696
   697    // This function creates a child processing instruction, returning a dataflex object.
   698    // The interface of the object returned can be used in AppendChild to add
   699    // the processing instruction to the XML Document.
   700
   701    Function CreateChildProcessingInstruction String sTarget String sValue Returns Handle
   702        Integer hoNewProcessingInstruction
   703        Integer hoDocumentObject
   704        Integer infcNewProcessingInstruction
   705        Integer iClassID
   706        Get DocumentObject to hoDocumentObject
   707        // Create an ProcessingInstruction in the document and assign its interface to the new DF object.
   708        Get createProcessingInstruction of hoDocumentObject sTarget sValue to infcNewProcessingInstruction
   709        If infcNewProcessingInstruction  Begin // if there was an error, no infc handle would be returned
   710            Get NodeClassId of hoDocumentObject NODE_PROCESSING_INSTRUCTION to iClassId
   711            Get CreateXMLObject iClassID infcNewProcessingInstruction to hoNewProcessingInstruction
   712        End
   713        Function_Return hoNewProcessingInstruction
   714    End_Function
   715
   716    // This function creates a child text node, returning a dataflex object.
   717    // The interface of the object returned can be used in AppendChild to add
   718    // the text node to the XML Document.
   719
   720    Function CreateChildTextNode String sValue Returns Handle
   721        Integer hoNewTextNode
   722        Integer hoDocumentObject
   723        Integer infcNewTextNode
   724        Integer iClassID
   725        Get DocumentObject to hoDocumentObject
   726        // Create an TextNode in the document and assign its interface to the new DF object.
   727        Get createTextNode of hoDocumentObject sValue to infcNewTextNode
   728        If infcNewTextNode Begin // if there was an error, no infc handle would be returned
   729            Get NodeClassId of hoDocumentObject NODE_TEXT to iClassId
   730            Get CreateXMLObject iClassId infcNewTextNode to hoNewTextNode
   731        End
   732        Function_Return hoNewTextNode
   733    End_Function
   734
   735    // This function creates a cdata text node, returning a dataflex object.
   736    // The interface of the object returned can be used in AppendChild to add
   737    // the cdata node to the XML Document.
   738
   739    Function CreateCDATASectionNode String sValue Returns Handle
   740        Integer hoNewNode
   741        Integer hoDocumentObject
   742        Integer infcNewNode
   743        Integer iClassId
   744        // The DataFlex objects are created inside the nodes (elements).
   745        // Create an element in the document and assign its interface to the new DF object.
   746        Get DocumentObject to hoDocumentObject
   747        Get createCDATASection of hoDocumentObject sValue to infcNewNode
   748        If infcNewNode Begin
   749            Get NodeClassId of hoDocumentObject NODE_CDATA_SECTION to iClassId
   750            Get CreateXMLObject iClassId infcNewNode to hoNewNode
   751        End
   752        Function_Return hoNewNode
   753    End_Function
   754
   755    // Create a document fragment.  Document fragments can be used to house nodes temporarily. When
   756    // You append or insert a document fragment (appendNode InsertBeforeNode) child nodes are appended
   757    // to the destination object and not the fragment node itself. This is useful!
   758
   759    Function CreateDocumentFragmentNode Returns Handle
   760        Integer hoNew
   761        Integer hoDocumentObject
   762        Integer infcNew
   763        Integer iClassID
   764        Get DocumentObject to hoDocumentObject
   765        // Create an Comment in the document and assign its interface to the new DF object.
   766        Get createDocumentFragment of hoDocumentObject to infcNew
   767        If infcNew Begin // if there was an error, no infc handle would be returned
   768            Get NodeClassId of hoDocumentObject NODE_DOCUMENT_FRAGMENT to iClassId
   769            Get CreateXMLObject iClassId infcNew to hoNew
   770        End
   771        Function_Return hoNew
   772    End_Function
   773
   774    //  Create a Node of any passed Type (e.g. Node_element). Normally you don't need this as there are
   775    //  specific messages to do this for each node type. Node that this lets you pass namespaces as a separate
   776    //  parameter. With all of the other messages (e.g. createElementNode) you pass namespaces as prefixed to
   777    // the tagname (e.g. Get CreateElementNode "MyNameSpace:MyTag" "MyValue" to hoEle)
   778
   779    Function CreateChildNode Integer iNodeType String sTagName String sNameSpace Returns Handle
   780        Integer hoNewNode hoDocumentObject
   781        Integer infcNewNode
   782        Integer iClassid iType
   783        Get DocumentObject to hoDocumentObject
   784        Get NodeClassId iNodeType to iClassId
   785        If (iClassId<>0) Begin
   786            // Create a node in the document and assign its interface to the new DF object.
   787            Get createNode of hoDocumentObject iNodeType sTagName sNameSpace to infcNewNode
   788            // this is required to force the interface type to be correct.
   789            Move (invokexml(DF_IXMLDOMNODE, GET_piNodeType, infcNewNode, 0, 0, 0, 0)) to iType
   790            Move (invokexml(DF_IXMLDOMNODE, GET_ChangeNodeType, infcNewNode, iType, 1, 0, 0)) to infcNewNode
   791
   792            If infcNewNode ;
   793                Get CreateXMLObject iClassId infcNewNode to hoNewNode
   794        End
   795        Function_Return hoNewNode
   796    End_Function
   797
   798
   799
   800    // The Addxxxxx messages create a new node and appends it to the list. When used as a function,
   801    // the object handle is returned and must be disposed of later by the programmer.
   802    // When used as a procedure, the object is destroyed--it just does it and is done.
   803
   804    Function AddElement String sTagName String sValue Returns Handle
   805        Integer hoNewElement
   806        Get CreateElementNode sTagName sValue to hoNewElement
   807        If hoNewElement Get AppendNode hoNewElement to hoNewElement
   808        Function_Return hoNewElement
   809    End_Function
   810
   811    Procedure AddElement String sTagName String sValue
   812        Integer hoNewElement
   813        Get AddElement sTagName sValue to hoNewElement
   814        If hoNewElement ;
   815            Send Destroy to hoNewElement
   816        Else ;
   817            Error DFERR_XML_INTERNAL_ERROR (SFormat(C_$XmlMethodFailure, "msg_AddElement"))
   818    End_Procedure
   819
   820    // this returns the object, This is often needed
   821    Function CreateElementNodeNS String sNameSpace String sTagName String sValue Returns Handle
   822        Integer hoNewElement
   823        Get CreateChildNode NODE_ELEMENT sTagName sNameSpace to hoNewElement
   824        If (hoNewElement and sValue<>"") ;
   825            Set psText of hoNewElement to sValue
   826        Function_Return hoNewElement
   827    End_Procedure
   828
   829
   830    // this returns the object, This is often needed
   831    Function AddElementNS String sNameSpace String sTagName String sValue Returns Handle
   832        Integer hoNewElement
   833        Get CreateElementNodeNS sNameSpace sTagName sValue to hoNewElement
   834        If hoNewElement Begin
   835            Get AppendNode hoNewElement to hoNewElement
   836        End
   837        Function_Return hoNewElement
   838    End_Function
   839
   840    Procedure AddElementNS String sNameSpace String sTagName String sValue
   841        Integer hoNewElement
   842        Get AddElementNS sNameSpace sTagName sValue to hoNewElement
   843        If hoNewElement ;
   844            Send Destroy to hoNewElement
   845        Else ;
   846            Error DFERR_XML_INTERNAL_ERROR (SFormat(C_$XmlMethodFailure, "msg_AddElementNS"))
   847    End_Procedure
   848
   849    Function AddAttributeNode Handle hoNode Returns Handle
   850        Handle hInfc
   851        Get Set_AttributeNode (XmlInterface(hoNode)) to hInfc
   852        If hInfc ; // if ret value we have a replacement
   853            Set XmlInterface of hoNode to hInfc
   854        Function_Return hoNode
   855    End_Function
   856
   857//    // is this needed
   858//    Function AddAttributeNodeNS handle hoNode returns Handle
   859//        Get AddAttributeNode hoNode to hoNode
   860//        function_return hoNode
   861//    End_Function
   862
   863    Function AttributeValueNode String sName Returns Handle
   864        Handle hInfc
   865        Handle hoNode
   866        Get AttributeNode sName to hInfc
   867        If hInfc ; // if ret value we have a replacement
   868           Get CreateXMLNode hInfc to hoNode
   869        Function_Return hoNode
   870    End_Function
   871
   872    Function AttributeValueNodeNS String sNameSpace String sBaseName Returns Handle
   873        Handle hoAttrs hoAttr
   874        String sValue
   875        Get TempAttributeNodes to hoAttrs
   876        If hoAttrs Begin
   877            Get QualifiedNode of hoAttrs sNamespace sBaseName to hoAttr
   878            Set XMLInterface of hoAttrs to 0
   879        End
   880        Function_Return hoAttr
   881    End_Function
   882
   883
   884    Function CreateAttributeNodeNS String sNameSpace String sName String sValue Returns Handle
   885        Integer hoNewAttribute
   886        Get CreateChildNode NODE_ATTRIBUTE sName sNameSpace to hoNewAttribute
   887        If hoNewAttribute ;
   888            Set psText of hoNewAttribute to sValue
   889        Function_Return hoNewAttribute
   890    End_Function
   891
   892    Procedure AddAttributeNS String sNameSpace String sName String sValue
   893       Handle hoNode
   894       Get CreateAttributeNodeNS sNameSpace sName sValue to hoNode
   895       If hoNode Begin
   896          Get AddAttributeNode hoNode to hoNode
   897          If hoNode Send Destroy of hoNode
   898       End
   899       Else ;
   900            Error DFERR_XML_INTERNAL_ERROR (SFormat(C_$XmlMethodFailure, "msg_AddAttributeNS"))
   901    End_Procedure
   902
   903
   904    // This function encapsulates creation and addition of attributes to a node.
   905    // should only work with element class
   906    Procedure AddAttribute String sName String sValue
   907        Set AttributeValue sName to sValue
   908    End_Procedure
   909
   910    // This function encapsulates creation and addition of comments to a node.
   911    // The return value is a Boolean that is currently unused.
   912
   913    Procedure AddChildComment String sValue
   914        Integer hoNewNode
   915        Get createChildComment sValue to hoNewNode
   916        If not hoNewNode ;
   917            Error DFERR_XML_INTERNAL_ERROR (SFormat(C_$XmlMethodFailure, "msg_AddChildComment"))
   918        Else Begin
   919            Get AppendNode hoNewNode to hoNewNode
   920            Send Destroy to hoNewNode
   921        End
   922    End_Procedure
   923
   924    // This function encapsulates creation and addition of processing instructions to a node.
   925    // The return value is a Boolean that is currently unused.
   926
   927    Procedure AddChildProcessingInstruction String sTarget String sValue
   928        Integer hoNewNode
   929        Get createChildProcessingInstruction sTarget sValue to hoNewNode
   930        If not hoNewNode ;
   931            Error DFERR_XML_INTERNAL_ERROR (SFormat(C_$XmlMethodFailure, "msg_AddChildProcessingInstruction"))
   932        Else Begin
   933            Get AppendNode hoNewNode to hoNewNode
   934            Send Destroy to hoNewNode
   935        End
   936    End_Procedure
   937
   938
   939    // This function encapsulates creation and addition of text nodes to a node.
   940    // The return value is a Boolean that is currently unused.
   941
   942    Procedure AddChildTextNode String sValue
   943        Integer hoNewNode
   944        Get createChildTextNode sValue to hoNewNode
   945        If not hoNewNode ;
   946            Error DFERR_XML_INTERNAL_ERROR (SFormat(C_$XmlMethodFailure, "msg_AddChildTextNode"))
   947        Else Begin
   948            Get AppendNode hoNewNode to hoNewNode
   949            Send Destroy to hoNewNode
   950        End
   951    End_Procedure
   952
   953    // This procedure encapsulates creation and addition of cdata text nodes to a node.
   954    Procedure AddCDataSection String sValue
   955        Handle hoNewNode
   956        Get CreateCDATASectionNode sValue to hoNewNode
   957        If not hoNewNode ;
   958            Error DFERR_XML_INTERNAL_ERROR (SFormat(C_$XmlMethodFailure, "msg_AddCDataSection"))
   959        Else Begin
   960            Get AppendNode hoNewNode to hoNewNode
   961            Send Destroy to hoNewNode
   962        End
   963    End_Procedure
   964
   965
   966    Function AddChildNode Integer iNodeType String sTagName String sNameSpace Returns Handle
   967        Integer hoNewNode
   968        Integer hoDocumentObject
   969        Get DocumentObject to hoDocumentObject
   970        Get createChildNode of hoDocumentObject iNodeType sTagName sNamespace to hoNewNode
   971        If hoNewNode ;
   972            Get AppendNode hoNewNode to hoNewNode
   973        Function_Return hoNewNode
   974    End_Function
   975    
   976    // don't use the runtime/msxml version of this. Instead just return the
   977    // first text from the first child node. This is much faster
   978    { NoDoc=True }
   979    Function psText Returns String
   980        Handle hText
   981        String sValue
   982        Get phFirstChild to hText
   983        Get InfcNodeValue hText to sValue
   984        Function_Return sValue        
   985    End_Function
   986     
   987    // Use this to call the internal Text property. This returns all text for all child
   988    // node. You rarely would want to do this. The is uses the msxml psText which can 
   989    // get slow with very large files. If for some reason you need all of the child node's
   990    // text and the file is large, you might want to consider doing this process manually.
   991    Function AllChildNodesText Returns String
   992        String sValue
   993        Forward Get psText to sValue
   994        Function_Return sValue        
   995    End_Function
   996    
   997    // return the interface NodeValue without having to create a
   998    // new object
   999    { Visibility=Private }
  1000    Function InfcNodeValue Handle hInfc Returns String
  1001        Integer hoDocument hoTempNode
  1002        String sValue
  1003        If (hinfc) Begin
  1004            Get DocumentObject to hoDocument
  1005            Get phoTempDomNode of hoDocument to hoTempNode
  1006            Set XMLInterface of hoTempNode to hInfc
  1007            Get psNodeValue of hoTempNode to sValue
  1008            Set XMLInterface of hoTempNode to 0
  1009        End
  1010        Function_Return sValue
  1011    End_Function
  1012    
  1013    // ChildNodeValue is used to get the "value" of an element. This is useful when the element
  1014    // only has a single value (similar to an attribute).
  1015    
  1016    Function ChildNodeValue String sTagName Returns String
  1017        Integer hoTempNode hoDocument
  1018        Integer hinfcTempNode 
  1019        String sRetVal
  1020        Get SelectSingleNode sTagName to hinfcTempNode
  1021        If (hinfcTempNode <> 0) Begin
  1022            Get DocumentObject to hoDocument
  1023            Get phoTempDomNode of hoDocument to hoTempNode
  1024            Set XMLInterface of hoTempNode to hinfcTempNode
  1025            Get phFirstChild of hoTempNode to hinfcTempNode
  1026            Set XMLInterface of hoTempNode to 0
  1027            If hinfcTempNode Begin
  1028                Get InfcNodeValue hinfcTempNode to sRetVal
  1029            End
  1030        End
  1031        Function_Return sRetVal
  1032    End_Function
  1033
  1034    // This simple function allows a parent to change the text of one of its elements.
  1035    // This actually occurs quite a bit, because (as stated above) lowest level
  1036    // elements are frequently used as properties.
  1037    //
  1038    Procedure SetChildNodeValue String sTagName String sValue
  1039        Integer hoTempNode
  1040        Integer hinfcTempNode
  1041        // Search for the node that matches.
  1042        Get SelectSingleNode sTagName to hinfcTempNode
  1043        // If no match is found, add a new element with the tag.
  1044        If (hinfcTempNode = 0) ;
  1045            Send AddElement sTagName sValue
  1046        Else Begin
  1047            Get CreateXMLObject U_BaseXMLDOMNode hinfcTempNode to hoTempNode
  1048            If hoTempNode Begin
  1049                // Set the text of the element.
  1050                Set psText of hoTempNode to sValue
  1051                Send Destroy to hoTempNode
  1052            End
  1053            Else ;
  1054                Error DFERR_XML_INTERNAL_ERROR (SFormat(C_$XmlMethodFailure, "msg_SetChildNodeValue"))
  1055        End
  1056    End_Procedure
  1057
  1058    // These messages are used to allow you to travese through a nodes.
  1059
  1060    Function FirstChild Returns Handle
  1061        Handle hoChild
  1062        Integer hinfcChild
  1063        Get phFirstChild  to hinfcChild
  1064        If (hinfcChild) ;
  1065            Get CreateXMLNode hinfcChild to hoChild
  1066        Function_Return hoChild
  1067    End_Function
  1068
  1069    Function NextSibling Returns Handle
  1070        Handle hoChild
  1071        Integer hinfcChild
  1072        Get phNextSibling  to hinfcChild
  1073        If (hinfcChild) ;
  1074            Get CreateXMLNode hinfcChild to hoChild
  1075        Function_Return hoChild
  1076    End_Function
  1077
  1078    Function PreviousSibling Returns Handle
  1079        Handle hoChild
  1080        Integer hinfcChild
  1081        Get phPreviousSibling  to hinfcChild
  1082        If (hinfcChild) ;
  1083            Get CreateXMLNode hinfcChild to hoChild
  1084        Function_Return hoChild
  1085    End_Function
  1086
  1087    Function LastChild Returns Handle
  1088        Handle hoChild
  1089        Integer hinfcChild
  1090        Get phLastChild  to hinfcChild
  1091        If (hinfcChild) ;
  1092            Get CreateXMLNode hinfcChild to hoChild
  1093        Function_Return hoChild
  1094    End_Function
  1095
  1096    // return an object that is the parent of the current node
  1097    Function ParentNode Returns Handle
  1098        Handle hoId
  1099        Handle hinfcXMLInterface
  1100        Get phParentNode to hinfcXMLInterface
  1101        If (hinfcXMLInterface) ;
  1102            Get CreateXmlNode hinfcXMLInterface to hoID
  1103        Function_Return hoID
  1104    End_Function
  1105
  1106    // Same as NextSibling except it uses or destroys the current node
  1107    //
  1108    // optimized version does not destroy/create object unless it needs to.  
  1109    // if the next node is the same node type we will resuse this object
  1110    // else this object is destroyed 
  1111    Function NextNode Returns Handle
  1112        Handle hoNode hoDocument
  1113        Handle hInfc
  1114        Get phNextSibling to hInfc
  1115        If hInfc Begin
  1116            Get DocumentObject to hoDocument
  1117            Move Self to hoNode
  1118            Send BindXMLInfc of hoDocument hInfc (&hoNode)
  1119        End
  1120        Else Begin
  1121            Send Destroy
  1122            Move 0 to hoNode
  1123        End
  1124        Function_Return hoNode
  1125    End_Function
  1126        
  1127        
  1128    // Enumerate through all nodes.
  1129
  1130    Procedure EnumerateNodes Integer iMsg Integer hoReceiver String sVal1 String sVal2
  1131        Integer i iLen
  1132        Integer hoNode
  1133        Integer hoNodeCollection
  1134        Get ChildNodes to hoNodeCollection
  1135        If (hoNodeCollection <> 0) Begin
  1136            Get NodeListLength of hoNodeCollection to iLen
  1137            Decrement iLen
  1138            For i from 0 to iLen
  1139                // For each record, process its fields.
  1140                Get CollectionNode of hoNodeCollection i to hoNode
  1141                Send iMsg of hoReceiver hoNode sVal1 sVal2
  1142                Send Destroy of hoNode
  1143            Loop
  1144            Send Destroy of hoNodeCollection
  1145        End
  1146    End_Procedure
  1147
  1148    // Enumerate through all elements.
  1149
  1150    Procedure EnumerateElements Integer iMsg Integer hoReceiver String sVal1 String sVal2
  1151        Integer i iLen
  1152        Integer hoNode
  1153        Integer hoNodeCollection
  1154        Get ChildNodes to hoNodeCollection
  1155        If (hoNodeCollection <> 0) Begin
  1156            Get NodeListLength of hoNodeCollection to iLen
  1157            Decrement iLen
  1158            For i from 0 to iLen
  1159                // For each record, process its fields.
  1160                Get CollectionNode of hoNodeCollection i to hoNode
  1161                If (piNodeType(hoNode)=NODE_ELEMENT) ;
  1162                    Send iMsg of hoReceiver hoNode sVal1 sVal2
  1163                Send Destroy of hoNode
  1164            Loop
  1165            Send Destroy of hoNodeCollection
  1166        End
  1167    End_Procedure
  1168
  1169
  1170    // enumerate through all attributes. There is no recurse here because attributes will not
  1171    // contain attributes.
  1172
  1173    Procedure EnumerateAttributes Integer iMsg Integer hoReceiver String sSomeValue
  1174        Integer i iLen
  1175        Integer hoNode
  1176        Integer hoNodeMapCollection
  1177        // we don't use tempattributenodes because we don't know what the enum message will do.
  1178        Get AttributeNodes to hoNodeMapCollection
  1179        If (hoNodeMapCollection <> 0) Begin
  1180            Get NodeListLength of hoNodeMapCollection to iLen
  1181            Decrement iLen
  1182            For i from 0 to iLen
  1183                // For each record, process its fields.
  1184                Get CollectionNode of hoNodeMapCollection i to hoNode
  1185                Send iMsg of hoReceiver hoNode sSomeValue
  1186                Send Destroy of hoNode
  1187            Loop
  1188            Send Destroy of hoNodeMapCollection
  1189        End
  1190    End_Procedure
  1191
  1192
  1193    Function XSLTransformation Integer hoXSLDocument Returns String
  1194        Integer infcXSLStartAt
  1195        String sBuffer
  1196        // Transformation is of current object using passed XSLDocument.
  1197        Get XMLInterface of hoXSLDocument to infcXSLStartAt
  1198        Get TransformNode infcXSLStartAt to sBuffer
  1199        Function_Return sBuffer
  1200    End_Function
  1201
  1202    // This allows for transformations not limited to the size of the string buffer
  1203    //
  1204    // Note that it is up to the programmer to dispose of the memory allocated at pBuffer
  1205    // by using the free(pBuffer) function
  1206    //
  1207    Function XSLTransformationToAddress Integer hoXSLDocument Returns Address
  1208        Integer infcXSLStartAt
  1209        Address pBuffer
  1210        // Transformation is of current object using passed XSLDocument.
  1211        Get XMLInterface of hoXSLDocument to infcXSLStartAt
  1212        Get TransformNodeToAddress infcXSLStartAt to pBuffer
  1213        Function_Return pBuffer
  1214    End_Function
  1215
  1216
  1217    // extract base name from string. e.g.: ns:name --> name
  1218    //
  1219    Function BaseNameFromQName String sName Returns String
  1220        Integer iPos
  1221        Move (Pos(":",sName)) to iPos
  1222        If iPos Begin
  1223            Move (remove(sName,1,iPos)) to sName
  1224        End
  1225        Function_Return sName
  1226    End_Function
  1227
  1228    // extract prefix name from string. e.g.: ns:name --> ns
  1229    //
  1230    Function PrefixNameFromQName String sName Returns String
  1231        String sPreFix
  1232        Integer iPos
  1233        Move (Pos(":",sName)) to iPos
  1234        If iPos Begin
  1235            Move (Left(sName,iPos-1)) to sPreFix
  1236        End
  1237        Function_Return sPreFix
  1238    End_Function
  1239
  1240
  1241    // Returns true if node is element and namespace and base name match
  1242    //
  1243    Function IsElementNS String sNamespaceURI String sBaseName Returns Boolean
  1244         Function_Return (piNodeType(Self)=NODE_ELEMENT and ;
  1245                          psNameSpaceURI(Self)=sNamespaceURI and ;
  1246                          psBaseName(Self)=sBaseName )
  1247    End_Function
  1248
  1249    // Returns node of first occurence of child node matching namespace and base name
  1250    //
  1251    Function ChildElementNS String sNameSpaceURI String sBaseName Returns Handle
  1252        Handle hoNode
  1253        Get FirstChild to hoNode
  1254        While (hoNode and not(IsElementNS(hoNode, sNameSpaceURI, sBaseName)))
  1255            Get NextNode of hoNode to hoNode
  1256        End
  1257        Function_Return hoNode
  1258    End_Function
  1259
  1260    // Returns node of next occurence of sibling node matching namespace and base name
  1261    // and destroys the current node.
  1262//    Function NextElementNS String sNameSpaceURI String sBaseName Returns Handle
  1263//        handle hoNode
  1264//        Get NextSibling to hoNode
  1265//        While (hoNode and not(IsElementNS(hoNode, sNameSpaceURI, sBaseName)))
  1266//            Get NextNode of hoNode to hoNode
  1267//        end
  1268//        Send Destroy
  1269//        function_return hoNode
  1270//    end_function
  1271
  1272    Function NextElementNS String sNameSpaceURI String sBaseName Returns Handle
  1273        Handle hoNode
  1274        // NextNode may return the same object or it may destroy the object and
  1275        // return nothing or a different object
  1276        Get NextNode to hoNode
  1277        While (hoNode and not(IsElementNS(hoNode, sNameSpaceURI, sBaseName)))
  1278            // use of hoNode is required. This can be different than self
  1279            Get NextNode of hoNode to hoNode
  1280        End
  1281         
  1282        Function_Return hoNode
  1283    End_Function
  1284
  1285
  1286    // Returns value (string) first occurence of child node matching namespace and base name
  1287    //
  1288    Function ChildElementValueNS String sNameSpaceURI String sBaseName Returns String
  1289        Handle hoNext
  1290        String sText
  1291        Get ChildElementNS sNameSpaceURI sBaseName to hoNext
  1292        If hoNext Begin
  1293            Get psText of hoNext to sText
  1294            Send destroy of hoNext
  1295        End
  1296        Function_Return sText
  1297    End_Function
  1298
  1299    Procedure SetChildElementValueNS String sNameSpaceURI String sBaseName String sValue
  1300        Integer hoNode
  1301        Integer hinfcTempNode
  1302        Get ChildElementNS sNameSpaceURI sBaseName to hoNode
  1303        If (hoNode=0) Begin
  1304            Send AddElementNS sNameSpaceURI sBaseName sValue
  1305        End
  1306        Else Begin
  1307            Set psText of hoNode to sValue
  1308            Send destroy of hoNode
  1309        End
  1310    End_Procedure
  1311
  1312
  1313//    // Returns node of first occurence of child node matching namespace and base name
  1314//    // that has an attrib value that contains a specified value
  1315//    //
  1316//    //Doc/ Visibility=Public
  1317//    Function FindElementNodeWithAttribNS string sNamespace string sBaseName string sAttribName string sAttribValue returns handle
  1318//        handle hoNext hoNode
  1319//        string sName
  1320//        Get FirstChild to hoNode
  1321//        While (hoNode)
  1322//            If (IsElementNS(hoNode, sNameSpace, sBaseName)) begin
  1323//                Get AttributeValue of hoNode sAttribName to sName
  1324//                If (sName=sAttribValue) Begin
  1325//                    Function_return hoNode
  1326//                end
  1327//            end
  1328//            Get NextSibling of hoNode to hoNext
  1329//            Send Destroy of hoNode
  1330//            Move hoNext to hoNode
  1331//        end
  1332//        function_return 0
  1333//    end_function
  1334
  1335    // pass a prefix and try to finds its NameSpaceURI. Start at current node and work up to parent.
  1336    // This can be useful when a qualified name is found in an attribute value
  1337    //
  1338    Function PrefixToNamespaceURI String sPrefix Returns String
  1339        Handle hoNode
  1340        Integer i iNodes
  1341        Integer hoNodes hoParentNode hoAttNode
  1342        Boolean bDone bParent
  1343        String sAttPrefix sName sNameSpace
  1344
  1345        Move Self to hoNode
  1346        While not bDone
  1347            Get TempAttributeNodes of hoNode to hoNodes
  1348            If (hoNodes <> 0) Begin
  1349                Get NodeListLength of hoNodes to iNodes
  1350                For i from 0 to (iNodes-1)
  1351                    // For each record, process its fields.
  1352                    Get CollectionNode of hoNodes i to hoAttNode
  1353                    Get psPrefix of hoAttNode to sAttPrefix
  1354                    Get psBaseName of hoAttNode to sName
  1355                    // with legacy msxml, xmlns="foo" returns psPrefix="xmlns" and pbBaseName=""
  1356                    // with newer msxml, xmlns="foo" returns psPrefix="" and pbBaseName="xmlns"
  1357                    // We handle both cases here. 
  1358                    
  1359                    If ( (sAttPrefix="xmlns" and sName=sPrefix) or ; // if a normal xmlns:xx="foo" match (sPrefix="xx") or a legacy xmlns="foo" match (sPrefix="")
  1360                         (sPrefix="" and sAttPrefix="" and sName="xmlns") ) Begin // special test for newer msxml xmlns="foo" match (sPrefix="")
  1361
  1362                        Get Value of hoAttNode to sNameSpace
  1363                        Move True to bDone
  1364                        Move (iNodes-1) to i
  1365
  1366                    End
  1367
  1368                    Send Destroy of hoAttNode
  1369                Loop
  1370                Set XMLInterface of hoNodes to 0
  1371            End
  1372            
  1373            Get ParentNode of hoNode to hoParentNode
  1374            If bParent Send destroy of hoNode
  1375            If not bDone Begin
  1376                If not hoParentNode Move True to bDone
  1377                Else Begin
  1378                    Move True to bParent
  1379                    Move hoParentNode to hoNode
  1380                End
  1381            End
  1382        End
  1383        Function_Return sNameSpace
  1384    End_Function
  1385
  1386
  1387
  1388End_Class
  1389
  1390// Set up basic inheritance for specialized forms of XML classes.
  1391// This needs to be done so we can make objects of these types.
  1392
  1393{ ClassLibrary=Common }
  1394{ HelpTopic=cXMLDOMElement }
  1395Class cXMLDOMElement is a BaseXmlDomElement
  1396    Import_Class_Protocol cXMLDOMNodeMixin
  1397
  1398// Send AddAttribute
  1399// Get  AddAttributeNode
  1400// Send RemoveAttribute
  1401// Get  AttributeValue
  1402// Get  AttributeValueNode
  1403
  1404// Send AddAttributeNS
  1405// Get  AddAttributeNodeNS
  1406// Send RemoveAttributeNs
  1407// Get  AttributeValueNS
  1408// Get  AttributeValueNodeNS
  1409
  1410    // Should use AddAttributeValue...does same thing
  1411    Procedure SetAttributeValue String sName String sValue
  1412        Send AddAttribute sName sValue
  1413    End_Procedure
  1414
  1415    // Note: Get_AttributeValue already there
  1416
  1417    Procedure RemoveAttribute String sName
  1418        Integer iVal
  1419        Get RemoveAttribute sName to iVal
  1420    End_Procedure
  1421
  1422    Function AttributeValueNS String sNameSpace String sBaseName Returns String
  1423        String sValue
  1424        Handle hinfcItem
  1425        Handle hoDoc hoTempAttributeNodes hoNode
  1426        Integer hinfcAttributes
  1427        
  1428//        // test if the basename attribute exists at all. This is an opimization as this
  1429//        // message is much faster allowing for quicker false matches (good for client web-services).
  1430//        Get AttributeValue sBaseName to sValue // doesn't work as expected
  1431//        If (sValue<>"") Begin 
  1432            Get TempAttributeNodes to hoTempAttributeNodes
  1433            Get QualifiedItem of hoTempAttributeNodes sBaseName sNameSpace  to hinfcItem
  1434            Set XMLInterface of hoTempAttributeNodes to 0
  1435            If hinfcItem Begin
  1436                Get DocumentObject to hoDoc
  1437                Get phoTempDomNode of hoDoc to hoNode
  1438                Set XMLInterface of hoNode to hinfcItem
  1439                Get psNodeValue of hoNode to sValue
  1440                Set XMLInterface of hoNode to 0
  1441            End
  1442//        End
  1443        Function_Return sValue
  1444    End_Function
  1445
  1446// replaced with optimized version above
  1447//    Function AttributeValueNS String sNameSpace String sBaseName Returns String
  1448//        Handle hoAttr
  1449//        String sValue
  1450//
  1451//        Get AttributeValueNodeNS sNameSpace sBaseName to hoAttr
  1452//        If hoAttr Begin
  1453//            Get Value of hoAttr to sValue
  1454//            Send destroy of hoAttr
  1455//        End
  1456//        function_return sValue
  1457//    end_function
  1458
  1459    Procedure RemoveAttributeNS String sNameSpace String sBaseName
  1460        Handle hoAttrs hoAttr
  1461        String sValue
  1462        Get TempAttributeNodes to hoAttrs
  1463        If hoAttrs Begin
  1464            Get RemoveQualifiedNode of hoAttrs sNamespace sBaseName to hoAttr
  1465            Set XMLInterface of hoAttrs to 0
  1466            If hoAttr ;
  1467                Send destroy of hoAttr
  1468        End
  1469    End_Procedure
  1470
  1471End_Class
  1472
  1473{ ClassLibrary=Common }
  1474{ HelpTopic=cXMLDOMNode }
  1475Class cXMLDOMNode is a BaseXmlDomNode
  1476    Import_Class_Protocol cXMLDOMNodeMixin
  1477End_Class
  1478
  1479{ ClassLibrary=Common }
  1480{ HelpTopic=cXMLDOMAttribute }
  1481Class cXMLDOMAttribute is a BaseXmlDomAttribute
  1482    Import_Class_Protocol cXMLDOMNodeMixin
  1483End_Class
  1484
  1485{ ClassLibrary=Common }
  1486{ HelpTopic=cXMLDOMComment }
  1487Class cXMLDOMComment is a BaseXmlDomComment
  1488    Import_Class_Protocol cXMLDOMNodeMixin
  1489End_Class
  1490
  1491{ ClassLibrary=Common }
  1492{ HelpTopic=cXMLDOMProcessingInstruction }
  1493Class cXMLDOMProcessingInstruction is a BaseXmlDomProcessingInstruction
  1494    Import_Class_Protocol cXMLDOMNodeMixin
  1495End_Class
  1496
  1497{ ClassLibrary=Common }
  1498{ HelpTopic=cXMLDOMTextNode }
  1499Class cXMLDOMTextNode is a BaseXmlDomTextNode
  1500    Import_Class_Protocol cXMLDOMNodeMixin
  1501End_Class
  1502
  1503{ ClassLibrary=Common }
  1504{ HelpTopic=cXMLDOMCDATASection }
  1505Class cXMLDOMCDATASection is a BaseXmlDomCDATASection
  1506    Import_Class_Protocol cXMLDOMNodeMixin
  1507End_Class
  1508
  1509{ ClassLibrary=Common }
  1510{ HelpTopic=cXMLDOMDocumentType }
  1511Class cXMLDOMDocumentType is a BaseXmlDomDocumentType
  1512    Import_Class_Protocol cXMLDOMNodeMixin
  1513    
  1514
  1515//        Function EnumerateEntities Integer iMsg Integer hoReceiver Integer bEnumerate Integer iSomeValue Returns Handle
  1516//            Integer i
  1517//            Integer hoNode
  1518//            Integer hoNamedNodeMap
  1519//            Integer hinfcNamedNodeMap
  1520//            Integer iLength
  1521
  1522//            Get phEntities To hinfcNamedNodeMap
  1523
  1524//            showln "The interface of the named node map is " hinfcNamedNodeMap
  1525
  1526//            If (hinfcNamedNodeMap <> 0) Begin
  1527//                Get CreateXMLObject U_cXMLDOMNamedNodeMap hinfcNamedNodeMap to hoNamedNodeMap
  1528//                Get piLength Of hoNamedNodeMap To iLength
  1529//                Showln "There are " iLength " items in map"
  1530
  1531//                ///                For i From 0 To (NodeListLength(hoNamedNodeMap)-1)
  1532//                ///                    // For each record, process its fields.
  1533//                //                    Get CollectionNode Of hoNamedNodeMap i To hoNode
  1534//                //                    Send iMsg Of hoReceiver hoNode bEnumerate iSomeValue
  1535//                //                    Send Destroy_Object Of hoNode
  1536//                //                Loop
  1537//            End
  1538//            Send Destroy To hoNamedNodeMap
  1539//            Function_Return 0
  1540//        End_Function
  1541
  1542//        Function EnumerateNotations Integer iMsg Integer hoReceiver Integer bEnumerate Integer iSomeValue Returns Handle
  1543//            Integer i
  1544//            Integer hoNode
  1545//            Integer hoNamedNodeMap
  1546//            Integer hinfcNamedNodeMap
  1547//            Integer iLength
  1548
  1549//            Object oNamedNodeMap Is A cXMLDOMNamedNodeMap
  1550//                Move Self To hoNamedNodeMap
  1551//            End_Object
  1552
  1553//            Get phNotations To hinfcNamedNodeMap
  1554
  1555//            showln "The interface of the named node map is " hinfcNamedNodeMap
  1556
  1557//            If (hinfcNamedNodeMap <> 0) Begin
  1558//                Set XMLInterface Of hoNamedNodeMap To hinfcNamedNodeMap
  1559//                Get piLength Of hoNamedNodeMap To iLength
  1560//                Showln "There are " iLength " items in map"
  1561
  1562/////                For i From 0 To (NodeListLength(hoNamedNodeMap)-1)
  1563/////                    // For each record, process its fields.
  1564////                    Get CollectionNode Of hoNamedNodeMap i To hoNode
  1565////                    Send iMsg Of hoReceiver hoNode bEnumerate iSomeValue
  1566////                    Send Destroy_Object Of hoNode
  1567////                Loop
  1568//            End
  1569//            Send Destroy_Object To hoNamedNodeMap
  1570//            Function_Return 0
  1571//        End_Function
  1572
  1573End_Class
  1574
  1575{ ClassLibrary=Common }
  1576{ HelpTopic=cXMLDOMNotation }
  1577Class cXMLDOMNotation is a BaseXmlDomNotation
  1578    Import_Class_Protocol cXMLDOMNodeMixin
  1579End_Class
  1580
  1581{ ClassLibrary=Common }
  1582{ HelpTopic=cXMLDOMEntity }
  1583Class cXMLDOMEntity is a BaseXmlDomEntity
  1584    Import_Class_Protocol cXMLDOMNodeMixin
  1585End_Class
  1586
  1587{ ClassLibrary=Common }
  1588{ HelpTopic=cXMLDOMEntityReference }
  1589Class cXMLDOMEntityReference is a BaseXmlDomEntityReference
  1590    Import_Class_Protocol cXMLDOMNodeMixin
  1591End_Class
  1592
  1593{ ClassLibrary=Common }
  1594{ HelpTopic=cXMLDOMDocumentFragment }
  1595Class cXMLDOMDocumentFragment is a BaseXmlDomDocumentFragment
  1596    Import_Class_Protocol cXMLDOMNodeMixin
  1597End_Class
  1598
  1599
  1600{ ClassLibrary=Common }
  1601{ HelpTopic=cXMLDOMParseError }
  1602Class cXMLDOMParseError is a BaseXMLDomParseError
  1603    // returns an error sub-object as a sibling of this error object
  1604    Function ErrorItemNode Integer iItem Returns Handle
  1605        Handle hoParseErrorNode hoParent
  1606        Handle hParseErrorIntf
  1607        Get ErrorItem iItem to hParseErrorIntf
  1608        If (hParseErrorIntf) Begin
  1609            // add to parent in case developer destroys the current object
  1610            Get Parent to hoParent
  1611            Get Create of hoParent U_cXMLDOMParseError to hoParseErrorNode
  1612            Set XmlInterface of hoParseErrorNode to hParseErrorIntf
  1613        End
  1614        Function_Return hoParseErrorNode
  1615    End_Function         
  1616End_Class
  1617
  1618// Base document class with Base functions.
  1619
  1620{ ClassLibrary=Common }
  1621{ HelpTopic=cXMLDOMDocument }
  1622Class cXMLDOMDocument is an BaseXmlDomDocument
  1623
  1624    Import_Class_Protocol cXMLDOMNodeMixin
  1625
  1626    Procedure Construct_Object
  1627        Handle hInfc
  1628        Forward Send Construct_Object
  1629        Property String psDocumentName ""
  1630        { Visibility=Private }
  1631        Property Integer phPrivateDocumentElement 0
  1632        { Visibility=Private }
  1633        Property Handle phoTempDomNode (Create(Self,U_cXMLDomNode))
  1634        { Visibility=Private }
  1635        Property Handle phoTempDomNodeMap (Create(Self,U_cXMLDOMNamedNodeMap))
  1636        
  1637        // added in 15.1. If no COM pointer, msxml6 is most likely not installed. This will
  1638        // raise an unhandled error, which could be augmented to do something else.
  1639        Get XmlInterface to hInfc
  1640        If (hInfc=0) Begin
  1641            Send ErrorCreatingXMLObject
  1642        End
  1643    End_Procedure
  1644
  1645    // returns the classId for the passed NodeType. This is a good augmentation point. All nodes
  1646    // within an xml document come here to get a class. So, if you want to augment and return a
  1647    // different class, just check the node type and return whatever -- else forward
  1648
  1649    Function NodeClassId Integer iType Returns Integer
  1650        Integer iClassId
  1651        Case Begin
  1652            Case (iType=NODE_ELEMENT)                   Move U_cXMLDOMElement      to iClassId
  1653            Case (iType=NODE_ATTRIBUTE)                 Move U_cXMLDOMAttribute    to iClassId
  1654            Case (iType=NODE_TEXT)                      Move U_cXMLDOMTextNode     to iClassId
  1655            Case (iType=NODE_CDATA_SECTION)             Move U_cXMLDOMCDATASection to iClassId
  1656            Case (iType=NODE_ENTITY_REFERENCE)          Move U_cXMLDOMEntityReference to iClassId
  1657            Case (iType=NODE_ENTITY)                    Move U_cXMLDOMEntity       to iClassId
  1658            Case (iType=NODE_PROCESSING_INSTRUCTION)    Move U_cXMLDOMProcessingInstruction to iClassId
  1659            Case (iType=NODE_COMMENT)                   Move U_cXMLDOMComment      to iClassId
  1660            Case (iType=NODE_DOCUMENT)                  Move U_cXMLDOMDocument     to iClassId
  1661            Case (iType=NODE_DOCUMENT_TYPE)             Move U_cXMLDOMDocumentType to iClassId
  1662            Case (iType=NODE_DOCUMENT_FRAGMENT)         Move U_cXMLDOMDocumentFragment to iClassId
  1663            Case (iType=NODE_NOTATION)                  Move U_cXMLDOMNotation     to iClassId
  1664            Case (iType=0)                              Move 0                     to iClassId // this is an error!!
  1665            Case Else                                   Move U_cXMLDOMNode         to iClassId
  1666        Case End
  1667        Function_Return iClassId
  1668    End_Function
  1669
  1670    // Load an XML Document. The name of the document is stored in a property
  1671    // that must be set for this function to work correctly.
  1672
  1673    Function LoadXMLDocument Returns Integer
  1674        String sDocumentName
  1675        Integer bRetVal
  1676        Get psDocumentName to sDocumentName
  1677        Get LoadDocument sDocumentName to bRetVal
  1678        If (bRetVal = 0);
  1679            Function_Return True
  1680        Else;
  1681            Function_Return False
  1682    End_Function
  1683
  1684    Function SaveXMLDocument Returns Integer
  1685        String sDocumentName
  1686        Integer bRetVal
  1687        Get psDocumentName to sDocumentName
  1688        Get SaveDocument sDocumentName to bRetVal
  1689        Function_Return bRetVal
  1690    End_Function
  1691
  1692    // Load an XML from a string. This aguments the C message to ret 1 if Ok and 0 if error.
  1693    //
  1694    { Visibility=public }
  1695    Function LoadXML String sXML Returns Integer
  1696        Integer bRetVal
  1697        // for some reason the parser will not work properly with embedded double quotes.
  1698        // Change all " to ' in document.
  1699        //Move (replaces('"',sXML,"'")) to sXML  // removed this. Bad Idea.
  1700        Forward Get LoadXml sXML to bRetVal
  1701        If (bRetVal = 0) ;
  1702            Function_Return True
  1703        Else;
  1704            Function_Return False
  1705    End_Function
  1706
  1707    // Load an XML string from an address. This aguments the C message to ret 1 if Ok and 0 if error.
  1708    //
  1709    { Visibility=public }
  1710    Function LoadXMLFromAddress Address pXML Returns Integer
  1711        Integer bRetVal
  1712        Forward Get LoadXmlFromAddress pXML to bRetVal
  1713        If (bRetVal = 0) ;
  1714            Function_Return True
  1715        Else;
  1716            Function_Return False
  1717    End_Function
  1718
  1719
  1720    // Allow Nodes and Node node lists to get the parent document.
  1721
  1722    Function DocumentObject Returns Handle
  1723        Function_Return Self
  1724    End_Function
  1725
  1726    // Access to the root node allows for searches and iterations.
  1727    // The root node is a cNode.
  1728
  1729    Function DocumentElement Returns Handle
  1730        Integer hNewNode       // Object ID of Root Node
  1731        Integer infcNode   // XML Element Interface
  1732// we used to buffer this so we'd always return the same object. This is dangerous. If the devloper
  1733// deletes the root and then creates some other object with this name, we will have problems. Now we
  1734// always create a new root now - which means you can create multiple roots (which is probably ok).
  1735
  1736//        Get phPrivateDocumentElement to hNewNode
  1737//        // if for some reason the developer sends destroy to the root element then
  1738//        // we must check that acutally exists. If not, create the root all over again
  1739//        Get Object_Id of hNewNode to hNewNode // if Object no longer exists, 0 is returned
  1740//        If not (hNewNode) Begin
  1741//            // Call XML to get the document root element.
  1742//            Get phDocumentElement To infcNode
  1743//            If infcNode Begin
  1744//                Get CreateXMLObject U_cXMLDOMElement infcNode to hNewNode
  1745//                Set phPrivateDocumentElement to hNewNode
  1746//            end
  1747//        End
  1748
  1749        Get phDocumentElement to infcNode
  1750        If infcNode Begin
  1751            Get CreateXMLObject U_cXMLDOMElement infcNode to hNewNode
  1752            Set phPrivateDocumentElement to hNewNode // we no longer use this at all
  1753        End
  1754        Function_Return hNewNode
  1755    End_Function
  1756
  1757    //  CreateRootNode is used to set up the first element in a document.
  1758    //  It should only be used when creating new files.
  1759
  1760    Function CreateDocumentElement String sTagName Returns Handle
  1761        Integer hNewNode       // Object ID of Root Node
  1762        Integer infcNode   // XML Element Interface
  1763        // Call XML to create an element in the document.
  1764        Get CreateElement sTagName to infcNode
  1765        // Tie the element interface to the DataFlex object.
  1766        If infcNode ;
  1767            Get CreateXMLObject U_cXMLDOMElement infcNode to hNewNode
  1768        // Call XML to set the root element of the document.
  1769        Set phDocumentElement to infcNode
  1770        Set phPrivateDocumentElement to hNewNode
  1771        Function_Return hNewNode
  1772    End_Function
  1773
  1774    Function CreateDocumentElementNS String sNamespace String sTagName Returns Handle
  1775        Integer hNewNode       // Object ID of Root Node
  1776        Integer infcNode iType  // XML Element Interface
  1777        Get CreateElementNodeNS sNameSpace sTagName "" to hNewNode
  1778        Get XmlInterface of hNewNode to infcNode
  1779        Set phDocumentElement to infcNode
  1780        Set phPrivateDocumentElement to hNewNode
  1781        Function_Return hNewNode
  1782    End_Function
  1783
  1784
  1785
  1786    // return the DocType as a document-type object. Returns 0 if no dtd
  1787    // Access to information from the doc type object is limited. Use get psXML
  1788    Function DocTypeNode Returns Handle
  1789        Handle hinfcDocType hoDocType
  1790        Get phDocType to hinfcDocType
  1791        If hinfcDocType ;
  1792            Get CreateXMLObject U_cXMLDOMDocumentType hinfcDocType to hoDocType
  1793        Function_Return hoDocType
  1794    End_Function
  1795
  1796    Function phXMLErrorObject Returns Handle
  1797        Integer hoParseErrorObject
  1798        Integer hInfcParseError
  1799        Get phParseError to hInfcParseError
  1800        If hInfcParseError ;
  1801            Get CreateXMLObject U_cXMLDOMParseError hinfcParseError to hoParseErrorObject
  1802        Function_Return hoParseErrorObject
  1803    End_Function
  1804
  1805    //  The following procedure is meant to be overridden by one provided by the developer.
  1806
  1807    Procedure BasicParseErrorReport
  1808        String sProblem
  1809        String sLinePosition
  1810        String sDescr
  1811        String sReason
  1812        String sSource
  1813        Integer hoParseErrorObject
  1814        Get phXMLErrorObject to hoParseErrorObject
  1815        If hoParseErrorObject Begin
  1816            Move (SFormat(C_$CannotLoad, psDocumentName(Self)) + "."+character(13)+character(10)) to sProblem
  1817            Move (SFormat(C_$ParsingError, piLine(hoParseErrorObject), piLinePos(hoParseErrorObject))) to sLinePosition
  1818            Move (sLinePosition +character(13)+character(10)) to sLinePosition
  1819
  1820            Move (C_$Reason + ":" * (psReason(hoParseErrorObject))  +character(13)+character(10)) to sReason
  1821            Move (C_$Source + ":" * (psSrcText(hoParseErrorObject))) to sSource
  1822            Move (sProblem + sLinePosition + sReason + sSource) to sDescr
  1823            Error DFERR_XML_INTERNAL_ERROR sDescr
  1824            Send Destroy of hoParseErrorObject
  1825        End
  1826        Else ;
  1827            Error DFERR_XML_INTERNAL_ERROR C_$NotCreatedParseObject
  1828    End_Procedure
  1829
  1830    // bind an xml interface node to the passed XML object. If the
  1831    // object type is of the wrong type, we will destroy it and recreate it
  1832    // which is why hoNode is passed byRef.
  1833    // to use this you'd have to use the lower level private messages to get the
  1834    // xml interface handles and then bind them to an object. Just like in COM you could
  1835    // bind these to the same object, which might save some parsing time. This is made private
  1836    // because the time savings would probably be small and would not justify the extra
  1837    // complexity.
  1838    // It is a programming error to pass this a zero handle.
  1839    { Visibility=Private }
  1840    Procedure BindXMLInfc Handle hInfc Handle ByRef hoNode
  1841        Integer iType iClassId iType2
  1842        Get piNodeType of hoNode to iType2 // type of the DF XML object
  1843        
  1844        // Get the node type of the infc handle w/o creating a DF object
  1845        Move (invokexml(DF_IXMLDOMNODE, GET_piNodeType, hinfc, 0, 0, 0, 0)) to iType
  1846        Move (invokexml(DF_IXMLDOMNODE, GET_ChangeNodeType, hinfc, iType, 1, 0, 0)) to hInfc
  1847        If (hinfc=0) Begin
  1848            // this should not happen and we would need to know about this.
  1849            Error DFERR_XML_INTERNAL_ERROR (C_$XmlFailedNoDocObject + String(iType))
  1850            Function_Return 0
  1851        End
  1852        // if the type is the same we can reuse the current object and binding it to the interface pointer
  1853        If (iType=iType2) Begin
  1854            // resuse Self and return
  1855            Set XMLInterface of hoNode to hInfc
  1856        End
  1857        // if diffrent type, destroy the existing object and recreate it
  1858        Else Begin
  1859            Send Destroy of hoNode
  1860            Get NodeClassId iType to iClassId
  1861            Get CreateXMLObject iClassId hInfc to hoNode
  1862        End
  1863    End_Procedure
  1864    
  1865    { Visibility=Public }
  1866    Function ValidateDocument Returns Handle
  1867        Handle hParseErrorIntf hoParseError
  1868        Forward Get ValidateDocument to hParseErrorIntf
  1869        If hParseErrorIntf Begin
  1870            Get CreateXMLObject U_cXMLDOMParseError hParseErrorIntf to hoParseError
  1871        End
  1872        Function_Return hoParseError
  1873    End_Function
  1874    
  1875    { Visibility=Public }
  1876    Function AddExternalSchemaDocument String sSchema Handle hoSchema Returns Boolean
  1877        Handle hInfc
  1878        Boolean bOk
  1879        Get XmlInterface of hoSchema to hInfc
  1880        Forward Get AddExternalSchemaDocument sSchema hInfc to bOk
  1881        Function_Return (not(bOk))
  1882    End_Function
  1883        
  1884    { Visibility=Public }
  1885    Function AddExternalSchemaFile String sSchema String sFile Returns Boolean
  1886        Boolean bOk
  1887        Forward Get AddExternalSchemaFile sSchema sFile to bOk
  1888        Function_Return (not(bOk))
  1889    End_Function
  1890
  1891    { MethodType=Property }
  1892    { InitialValue="" }
  1893    Procedure Set psSelectionNamespaces String sNamespaces
  1894        Set psDomSecondLevelProperty "SelectionNamespaces" to sNamespaces
  1895    End_Procedure
  1896
  1897    { MethodType=Property }
  1898    Function psSelectionNamespaces Returns String
  1899        String  sNamespaces
  1900        Get psDomSecondLevelProperty "SelectionNamespaces" to sNamespaces
  1901        Function_Return sNamespaces
  1902    End_Function
  1903    
  1904    { MethodType=Property }
  1905    { InitialValue=False }
  1906    Procedure Set pbMultipleErrorMessages Boolean bMultipleErrors
  1907        Set pbDomSecondLevelProperty "MultipleErrorMessages" to bMultipleErrors
  1908    End_Procedure
  1909
  1910    { MethodType=Property }
  1911    Function pbMultipleErrorMessages Returns Boolean
  1912        Boolean bMultipleErrors
  1913        Get pbDomSecondLevelProperty "MultipleErrorMessages" to bMultipleErrors
  1914        Function_Return bMultipleErrors
  1915    End_Function
  1916    
  1917    Procedure ErrorCreatingXMLObject
  1918        Error DFERR_XML_INTERNAL_ERROR "Could not create XML COM object. MSXML6 may not be properly installed and registered."
  1919    End_Procedure
  1920    
  1921
  1922End_Class
  1923
  1924