ooRexx logo
./code/xmlDOM.cls/var/www/html/ooRexx/wip /** ********************************************************************** Copyright (c) 2011-2015 Ruurd J. Idenburg. All rights reserved. This program and the accompanying materials are made available under the terms of the Common Public License v1.0 which accompanies this distribution. A copy is also available at the following address: http://www.opensource.org/licenses/cpl1.0.php Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name or trademarks of Ruurd J. Idenburg nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. DISCLAIMER THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ********************************************************************** */ /* CLASS: xmlUtil */ /** xmlDom basic types and other useful things */ /** XML name valid characters. For (oo)Rexx, which only supports ASCII at the moment the valid range is alpha (lower and upper) and digits, plus '.', '-', '_' and' :' (this last one for qualified names (i.e. namespace:tag)). @return valid - A string containing the valid characters for a XML name */ ::routine xmlValidName public valid = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.-_:' return valid /** Generates a "under construction" message for things not yet operational. @param name - The name of the thing the message is about @return message - The message text */ ::routine isUnderConstruction public use strict arg name message = name "is currently under construction!" return message /** xmlDomString is a subclass of String, for the time being without any modifications. */ ::class xmlDomString public subclass string /** xmlDomTimeStamp represents a number of milliseconds */ ::class xmlDomTimeStamp public subclass string /** xmlDomUserData represents a reference to application data. */ ::class xmlDomUserData public /** xmlDomObject represents an object reference. */ ::class xmlDomObject public /** domExceptions and their codes. DOM operations only raise exceptions in "exceptional" circumstances, i.e., when an operation is impossible to perform (either for logical reasons, because data is lost, or because the implementation has become unstable). In general, DOM methods return specific error values in ordinary processing situations, such as out-of-bound errors when using NodeList. Implementations should raise other exceptions under other circumstances. For example, implementations should raise an implementation-dependent exception if a .nil argument is passed when null was not expected. Some languages and object systems do not support the concept of exceptions. For such systems, error conditions may be indicated using native error reporting mechanisms. For some bindings, for example, methods may return error codes similar to those listed in the corresponding method descriptions. */ ::class domException public /** INDEX_SIZE_ERR - If index or size is negative, or greater than the allowed value. */ ::method index_size_err class return 1 /** DOMSTRING_SIZE_ERR - If the specified range of text does not fit into a DOMString. */ ::method domstring_size_err class return 2 /** HIERARCHY_REQUEST_ERR - If any Node is inserted somewhere it doesn't belong. */ ::method hierarchy_request_err class return 3 /** WRONG_DOCUMENT_ERR - If a Node is used in a different document than the one that created it (that doesn't support it). */ ::method wrong_document_err class return 4 /** INVALID_CHARACTER_ERR - If an invalid or illegal character is specified, such as in an XML name. */ ::method invalid_character_err class return 5 /** NO_DATA_ALLOWED_ERR - If data is specified for a Node which does not support data */ ::method no_data_allowed_err class return 6 /** NO_MODIFICATION_ALLOWED_ERR - If an attempt is made to modify an object where modifications are not allowed. */ ::method no_modification_allowed_err class return 7 /** NOT_FOUND_ERR - If an attempt is made to reference a Node in a context where it does not exist. */ ::method not_found_err class return 8 /** NOT_SUPPORTED_ERR - If the implementation does not support the requested type of object or operation. */ ::method not_supported_err class return 9 /** INUSE_method_ERR - If an attempt is made to add an method that is already in use elsewhere. */ ::method inuse_method_err class return 10 /** INVALID_STATE_ERR - If an attempt is made to use an object that is not, or is no longer, usable. */ ::method invalid_state_err class return 11 /** SYNTAX_ERR - If an invalid or illegal string is specified. */ ::method syntax_err class return 12 /** INVALID_MODIFICATION_ERR - If an attempt is made to modify the type of the underlying object. */ ::method invalid_modification_err class return 13 /** NAMESPACE_ERR - If an attempt is made to create or change an object in a way which is incorrect with regard to namespaces. */ ::method namespace_err class return 14 /** INVALID_ACCESS_ERR - If a parameter or an operation is not supported by the underlying object. */ ::method invalid_access_err class return 15 /** VALIDATION_ERR - If a call to a method such as insertBefore or removeChild would make the Node invalid with respect to "partial validity", this exception would be raised and the operation would not be done. This code is used in [DOM Level 3 Validation]. Refer to this specification for further information. */ ::method validation_err class return 16 /** TYPE_MISMATCH_ERR - If the type of an object is incompatible with the expected type of the parameter associated to the object. */ ::method type_mismatch_err class return 17 /* :end */ /* CLASS: xmlNodeList */ /** The xmlNodeList interface provides the abstraction of an ordered collection of xmlNodes, without defining or constraining how this collection is implemented. xmlNodeList objects in the DOM are live. For this ooRexx implementation a xmlNodeLIst is defined as a resticted array, whose members must be an instance of xmLNode. The items in the xmlNodeList are accessible via an integral index, starting from 0. */ ::class xmlNodeList public /** Provide the number of xmlNodes in the xmlNodeList. @return count - The number of items (xmlNodes) in the xmlNodeList. */ ::method length return self~nodeList~items /** The nodeList array can only be set by the xmlNodeList self */ ::attribute nodeList get ::attribute nodeList set /** xmlNodeList instance constructor. As the creation of the xmlNodeList is left to the implementer, for ooRexx the constructor expects to get the representation of the complete xmlNodeList as an ooRexx array. @param nodeList=(.array~new) - an ooRexx array of xmlNodes. */ ::method init use strict arg nodeList=(.array~new) if \nodeList~isA(.array) then raise syntax 93.914 array (nodeList, .Array) self~nodeList = nodeList exit /** Retrieve the xmlNode at index position. @param index - The index (base 0) of the wanted Node. @return node - The xmlNode at the index in the xmlNodeList, or .nil if not a valid index. */ ::method item use strict arg index node = .nil if index>=0 then node = self~nodeList[index+1] return node /** Add a xmlNode to the xmlNodeList. @param node - The xmlNode to be added to the xmlNodeList. @raises user domException - HIERARCHY_REQUEST_ERR */ ::method append use strict arg node if \node~isA(.xmlNode) then raise syntax 88.914 array (node, .xmlNode) self~nodeList~append(node) return /** Removes a xmlNode from the xmlNodeList. @param node - The xmlNode to be removed. @return node - The removed xmlNode or .nil, if not present. Note: On hold for possible future use */ ::method remove private protected use strict arg node node = self~nodelist~remove(node) return node /** @return array - A native ooRexx array representing the xmlNodeList. */ ::method toOorexxArray return self~nodeList /** Sets the xmlNodeList from a native ooRexx array. @param nodeArray - the native ooRexx array to replace an existing xmlNodeList. */ ::method fromOorexxArray use strict arg nodeArray do i=1 to nodeArray~items if \nodeArray[i]~isA(.xmlNode) then raise syntax 88.914 array (nodeArray[i], .xmlNode) end self~nodeList = nodeArray return /* :end */ /* CLASS: xmlNode */ /** The xmlNode class is the base class for real nodetypes such as elementNode and textNode. Methods that make no sense or that are just plain impossible to implement in this base class, because the implementation is only possible in a subclass will raise syntax error 93.963 - Unsupported or not implented method. Methods that have a default value (e.g. .nil) will be intialized to that default value and need to be overridden in the appropiate subclass. */ ::class xmlNode public /** A convenience constant to implement null */ ::constant null .nil /** Constants that define the type of nodes that are possible. */ ::constant elementNode 1 ::constant attributeNode 2 ::constant textNode 3 ::constant cdataSectionNode 4 ::constant entityReferenceNode 5 ::constant entityNode 6 ::constant processingInstructionNode 7 ::constant commentNode 8 ::constant documentNode 9 ::constant documentTypeNode 10 ::constant documentFragmentNode 11 ::constant notationNode 12 /** instances is a private class attribute (property) that is used to keep track of the node instances being created and to provide a unique identifier for each node. */ ::attribute instances class private /** Gets a unique identifier for each (subclass) node being created. @return number - unique identifier for the new xmlNode The use of use strict arg makes sure there are no parameters. */ ::method getId class use strict arg if instances~dataType('U') then instances = 0 instances += 1 return instances /** The unique node identification */ ::attribute id private /** A NamedNodeMap representing the attributes in an elementNode. */ ::attribute attributes get ::attribute attributes set /** The absolute base URI of this node or null if the implementation was not able to obtain an absolute URI. */ ::attribute baseURI get ::attribute baseURI set /** A nodeList containing the childNodes of a node. If there are no children, this is a NodeList containing no nodes. */ ::attribute childNodes get ::attribute childNodes set /** The local part of the qualified name of this node.
For nodes of any type other than ELEMENT_NODE and ATTRIBUTE_NODE and nodes created with a DOM Level 1 method, such as xmlDocument~createElement, this is always .nil. */ ::attribute localName get ::attribute localName set /** The namespace URI of this node, or null if it is unspecified. This is not a computed value that is the result of a namespace lookup based on an examination of the namespace declarations in scope. It is merely the namespace URI given at creation time.
For nodes of any type other than ELEMENT_NODE and ATTRIBUTE_NODE and nodes created with a DOM Level 1 method, such as xmlDocument~createElement, this is always .nil. */ ::attribute namespaceURI get ::attribute namespaceURI set /** */ ::attribute nextSibling /** The following nodeName values are valid for a particular type of node: */ ::attribute nodeName get ::attribute nodeName set /** An integer indicating which type of node this is. See above. */ ::attribute nodeType get ::attribute nodeType set /** The following nodeName values are valid for a particular type of node: */ ::attribute nodeValue get ::attribute nodeValue set /** The xmlDocument object associated with this node. This is also the xmlDocument object used to create new nodes. When this node is a xmlDocument or a xmlDocumentType which is not used with any xmlDocument yet, this is .nil. */ ::attribute ownerDocument get ::attribute ownerDocument set /** The parent of this node. All nodes, except xmlAttr, xmlDocument, xmlDocumentFragment, xmlEntity, and xmlNotation may have a parent. However, if a node has just been created and not yet added to the tree, or if it has been removed from the tree, this is .nil. */ ::attribute parentNode get ::attribute parentNode set /** The namespace prefix of this node, or null if it is unspecified. When it is defined to be .nil, setting it has no effect, including if the node is read-only. Note that setting this attribute, when permitted, changes the nodeName attribute, which holds the qualified name, as well as the tagName and name attributes of the xmlElement and xmlAttr interfaces, when applicable. Setting the prefix to null makes it unspecified, setting it to an empty string is implementation dependent. Note also that changing the prefix of an attribute that is known to have a default value, does not make a new attribute with the default value and the original prefix appear, since the namespaceURI and localName do not change. For nodes of any type other than ELEMENT_NODE and ATTRIBUTE_NODE and nodes created with a DOM Level 1 method, such as createElement from the xmlDocument interface, this is always .nil. */ ::attribute prefix get ::attribute prefix set /** */ ::attribute previousSibling /** This attribute returns the text content of this node and its descendants. When it is defined to be .nil, setting it has no effect. On setting, any possible children this node may have are removed and, if it the new string is not empty or null, replaced by a single xmlText node containing the string this attribute is set to. */ ::method textContent raise syntax 93.960 exit ::attribute textContent set /** Method to initially set read-only attributes @param attrName - the name of the Attribute. @param attrValue - the value of the attribute. @raises syntax 93.900 - Attribute value cannot be set twice If the attribute has been set already a syntx error will be raised */ ::method setReadOnly --trace i use strict arg attrName,attrValue if self~send(attrName)<>attrName~upper then raise syntax 93.900 array ("Attribute:" attrName "is read only, once set") else self~send(attrName'=',attrValue) return /** The instance constructor */ ::method init self~id = self~class~getId self~attributes = .nil self~baseURI = .nil self~childNodes = .xmlNodeList~new(.array~new) self~localName = .nil self~namespaceURI = .nil self~nodeName = '' self~nodeValue = '' self~nodeType = .nil self~ownerDocument = .nil self~parentNode = .nil self~prefix = .nil return /** Adds the node child to the end of the list of children of this node. If the child is already in the tree, it is first removed. @param child - the node to be appended. @return node - the node appended If child is a xmlDocumentFragment object, the entire contents of the document fragment are moved into the child list of this node. */ ::method appendChild use strict arg child appended = .nil if (child<>.nil) then do child~parentNode = self self~childNodes~append(child) appended = child end return appended /** @return nodes - A xmlNodeList that contains all the children of this node. If there are no children, then this is a xmlNodeList containing no nodes. */ ::method children use strict arg return self~childNodes /** Returns a duplicate of this node, i.e., serves as a generic copy constructor for nodes. The duplicate node has no parent (parentNode is .nil) and no user data. User data associated to the imported node is not carried over. However, if any UserDataHandlers has been specified along with the associated data these handlers will be called with the appropriate parameters before this method returns. @param deep=.false - optional .true or .false (= default) @return node - the duplicated node If deep is .true, recursively clone the subtree under the specified node; if .false, clone only the node itself (and its attributes, if it is an xmlElement). Cloning an xmlElement copies all attributes and their values, including those generated by the XML processor to represent defaulted attributes, but this method does not copy any children it contains unless it is a deep clone. This includes text contained in the xmlElement since the text is contained in a child xmlText node.
Cloning an xmlAttr directly, as opposed to be cloned as part of an xmlElement cloning operation, returns a specified attribute (specified is true). Cloning an xmlAttr always clones its children, since they represent its value, no matter whether this is a deep clone or not.
Cloning an xmlEntityReference automatically constructs its subtree if a corresponding xmlEntity is available, no matter whether this is a deep clone or not.
Cloning any other type of node simply returns a copy of this node.
Note that cloning an immutable subtree results in a mutable copy, but the children of an xmlEntityReference clone are readonly. In addition, clones of unspecified xmlAttr nodes are specified. And, cloning xmlDocument, xmlDocumentType, xmlEntity, and xmlNotation nodes is implementation dependent. */ ::method cloneNode use strict arg deep=.false clone = self~copy clone~parentNode = .nil if deep = .true then do raise syntax 93.963 end return clone /** Compares the reference node, i.e. the node on which this method is being called, with a node, i.e. the one passed as a parameter, with regard to their position in the document and according to the document order. @param other - The node to compare with @return number - Position relatively to the reference node */ ::method compareDocumentPosition use strict arg other raise syntax 93.963 exit /** @return child - The first child of this node If there is no such node, this returns .nil */ ::method firstChild use strict arg child = .nil if (self~childNodes~length>0) then child = self~Childnodes~item(0) return child /** @param feature - The name of the feature requested @param version - The version number of the feature to test @return domObject - An object which implements the specialized APIs or .nil This method returns a specialized object which implements the specialized APIs of the specified feature and version, as specified in DOM Features. The specialized object may also be obtained by using binding-specific casting methods but is not necessarily expected to.
This method also allows the implementation to provide specialized objects which do not support the xmlNode interface. */ ::method getFeature use strict arg feature, version raise syntax 93.963 exit /** Retrieves the object associated to a key on a this node. The object must first have been set to this node by calling setUserData with the same key. @param key - The key the object is associated to. @return userdata - the DOMUserData associated, or .nil if there was none */ ::method getUserData use strict arg key raise syntax 93.963 exit /** @return boolean - .true if this node has any attributes, .false otherwise */ ::method hasAttributes use strict arg return .false /** @return boolean - .true if this node has any children, .false otherwise */ ::method hasChildNodes use strict arg hasChildren = .false if (self~children~items>0) then hasChildren = .true return hasChildren /** Inserts the node child before the existing child node where. @param child - the node to be inserted @param where - the node before which the new node needs to be inserted. @return node - the node being inserted If where is .nil, insert child at the end of the list of children.
If child is a xmlDocumentFragment object, all of its children are inserted, in the same order, before where.
If the child is already in the tree, it is first removed.
Note: Inserting a node before itself is implementation dependent. */ ::method insertBefore use strict arg child, where if (where==.nil) then do self~childNodes~append(child) end -- find the where node else do newList = .xmlNodeList~new do i=0 to self~childNodes~length-1 if self~childNodes~item(i) == where then newList~append(child) newList~append(self~childNodes~item(i)) end self~childNodes = newList end child~parentNode = self return child /** This method checks if the specified namespaceURI is the default namespace or not. @param uri - The namespaceURI to look for @return boolean - .true if default, .false otherwise */ ::method isDefaultNamespace use strict arg uri raise syntax 93.963 exit /** Tests whether two nodes are equal. @param other - The node to compare equality with @return boolean - .true if equal, .false otherwise This method tests for equality of nodes, not sameness (i.e., whether the two nodes are references to the same object) which can be tested with xmlNode~isSameNode. All nodes that are the same will also be equal, though the reverse may not be true.
Two nodes are equal if and only if the following conditions are satisfied: For two xmlDocumentType nodes to be equal, the following conditions must also be satisfied: On the other hand, the following do not affect equality: the ownerDocument, baseURI, and parentNode attributes, the specified attribute for xmlAttr nodes, the schemaTypeInfo attribute for xmlAttr and xmlElement nodes, the xmlText~isElementContentWhitespace attribute for xmlText nodes, as well as any user data or event listeners registered on the nodes. */ ::method isEqualNode use strict arg other raise syntax 93.963 exit /** Tests whether this node is the same node as the given one. @param other - The node to test against. @return boolean - .true if the nodes are the same, .false otherwise. This method provides a way to determine whether two xmlNode references returned by the implementation reference the same object. When two xmlNode references are references to the same object, even if through a proxy, the references may be used completely interchangeably, such that all attributes have the same values and calling the same DOM method on either reference always has exactly the same effect. */ ::method isSameNode use strict arg other raise syntax 93.963 exit /** Tests whether the DOM implementation implements a specific feature and that feature is supported by this node, as specified in DOM Features. @param feature - The name of the feature to test. @param version - This is the version number of the feature to test. @return boolean - .true if supported on this node, .false otherwise. */ ::method isSupported use strict arg feature, version return .false /** @return aNode - The last child of this node. If there is no such node, this returns .nil. */ ::method lastChild use strict arg child = .nil if (self~children~items>0) then child = self~children[self~children~items] return child /** Look up the namespaceURI associated to the given prefix, starting from this node.
See Namespace URI Lookup for details on the algorithm used by this method. @param prefix - The prefix to look for. @return aString - The associated namespaceURI or .nil if none is found. If prefix is null, the method will return the default namespaceURI if any. */ ::method lookupNamespaceURI use strict arg prefix raise syntax 93.963 exit /** Look up the prefix associated to the given namespaceURI, starting from this node. @param uri - A string specifying the namespaceURI to look for @return aString - An associated namespace prefix or .nil if none is found The default namespace declarations are ignored by this method. See Namespace Prefix Lookup for details on the algorithm used by this method.
If more than one prefix are associated to the namespace prefix, the returned namespace prefix is implementation dependent. */ ::method lookupPrefix use strict arg uri raise syntax 93.963 exit /** Finds the next sibling. @return aNode - The node immediately following this node. If there is no such node, this returns .nil. */ /*::method nextSibling use strict arg sibling = .nil if (self~parentNode<>.nil) then do siblings = self~parentNode~childNodes do label next i=1 to siblings~items if (siblings[i]==self) then do if (i If the parameter "normalize-characters" of the DOMConfiguration object attached to the xmlNode~ownerDocument is .true, this method will also fully normalize the characters of the xmlText nodes.
Note: In cases where the document contains CDATASections, the normalize operation alone may not be sufficient, since XPointers do not differentiate between xmlText nodes and xmlCDATASection nodes. */ ::method normalize use strict arg raise syntax 93.963 exit /** Finds the preceding node. @return aNode - The node immediately preceding this node. If there is no such node, this returns .nil */ /** ::method previousSibling use strict arg sibling = .nil if (self~parentNode<>.nil) then do siblings = self~parentNode~childNodes do labl prev i=1 to siblings~items if (siblings[i]==self) then do if (i>1) then do sibling = siblings[i-1] leave prev end end end end return sibling */ /** Removes the child node indicated by aNode from the list of children, and returns it. @param child - The node being removed. @return aNode - The node removed. */ ::method removeChild use strict arg child removed = .nil if (child<>.nil) then do -- find the reference node do i=1 to self~children~items if (children[i]==child) then leave end removed = self~children~remove(i) removed~parentNode = .nil end return removed /** Replaces the child node old with new in the list of children, and returns the old child node. @param new - The new node to put in the child list. @param old - The node being replaced in the list. @return aNode - The node replaced. If new is a xmlDocumentFragment object, old is replaced by all of the xmlDocumentFragment children, which are inserted in the same order. If the new is already in the tree, it is first removed.
Note: Replacing a node with itself is implementation dependent. */ ::method replaceChild use strict arg new, old replaced = .nil if (old<>.nil) then do -- find the reference node do i=1 to self~children~items if (self~children[i]==old) then leave end replaced = self~children[i] self~children[i] = new self~children[i]~parentNode = self replaced~parentNode = .nil end return replaced /** Associate an object to a key on this node. The object can later be retrieved from this node by invoking the getUserData method with the same key. @param key - The key to associate the object to. @param data - A DOMUserData object to associate to the key, or null to remove any existing association to that key. @param handler - An UserDataHandler, a handler to associate to that key, or null. @return userData - The DOMUserData previously associated to the given key on this node, or null if there was none. */ ::method setUserData use strict arg key, data, handler raise syntax 93.963 exit /** Convenience method to walk thru a (sub)nodes tree @param nodes - The sibling xmlNodeList to start the walk. @param name - The name of the tag being searched for. @param nl - The xmlNodeList containing the selected result nodes. */ ::method treeWalk private use strict arg nodes, name, nl do n=0 to nodes~length-1 if name<>'*' then do if nodes~item(n)~nodeName==name then nl~append(nodes~item(n)) end else do nl~append(nodes~item(n)) end if nodes~item(n)~childNodes~length>0 then do self~treewalk(nodes~item(n)~childNodes, name, nl) end end return /* :end */ /* CLASS: xmlNamedNodeMap */ /** Objects implementing the xmlNamedNodeMap interface are used to represent collections of nodes that can be accessed by name. Note that xmlNamedNodeMap does not inherit from NodeList; NamedNodeMaps are not maintained in any particular order. Objects contained in an object implementing xmlNamedNodeMap may also be accessed by an ordinal index, but this is simply to allow convenient enumeration of the contents of a xmlNamedNodeMap, and does not imply that the DOM specifies an order to these xmlNodes. xmlNamedNodeMap objects in the DOM are live. */ ::class xmlNamedNodeMap public /** A private array with directory entries, that have a (possibly qualified) name as index and xmlNodes as items. */ ::attribute namedMap private /** xmlNamedNodeMap instance constructor. */ ::method init self~namedMap = .directory~new self~init:super exit /** The number of xmlNodes in this map. @return - The number of nodes in the xmlNamedNodeMap. */ ::method length return self~namedMap~items /** Retrieves a node specified by name. @param name - The nodeName of a node to retrieve. @return node - The xmlNode with the specified name, or .nil. */ ::method getNamedItem use strict arg name node = .nil if name~isA(.string) then do node = self~namedMap[name] end return node /** Retrieves a node specified by local name and namespace URI. @param namespaceURI - The namespace URI of the node to retrieve. @param localName - The local name of the node to retrieve. @return node - A xmlNode(of any type) with the specified local name and namespace URI, or null. Per [XML Namespaces], applications must use the value .nil, as the namespaceURI parameter for methods if they wish to have no namespace. */ ::method getNamedItemNS use strict arg namespaceURI, localName node = .nil if (localName)~isA(.string) then do node = self~namedMap[localName] if namespaceURI<>.nil then do if node~namespaceURI<>namespaceURI then node = .nil end end return node /** Returns the indexth item in the map. If index is greater than or equal to the number of nodes in this map, this returns .nil. @param index - Index into this map. @return node - The node at the indexth position in the map, or .nil if not a valid index. */ ::method item use strict arg index node = .nil if index>=0 then do node = self~namedMap~allItems[index+1] end return node /** Removes a node specified by name. @param name - The nodeName of the node to remove. @return node - The node removed from this map if a node with such a name exists. @raises user domException - NOT_FOUND_ERR When this map contains the attributes attached to an element, if the removed attribute is known to have a default value, an attribute immediately appears containing the default value as well as the corresponding namespace URI, local name, and prefix when applicable. This ooRexx implementation does not process a DTD, thus has no way to determine if a default value has to be provided. The node is only removed, no additional checks for default value are made. */ ::method removeNamedItem use strict arg name node = .nil if name~isA(.string) then do node = self~namedMap~remove(name) end if node==.nil then raise user domException description(.domException~not_found_err) return node /** Removes a node specified by local name and namespace URI. A removed attribute may be known to have a default value when this map contains the attributes attached to an element, as returned by the attributes attribute of the xmlNode interface. If so, an attribute immediately appears containing the default value as well as the corresponding namespace URI, local name, and prefix when applicable. @param namespaceURI=.nil - The namespace URI of the node to remove. @param localName - The local name of the node to remove. @return node - The node removed from this map if a node with such a name exists. @raises user domException - NOT_FOUND_ERR Per [XML Namespaces], applications must use the value .nil as the namespaceURI parameter for methods if they wish to have no namespace. @see #removeNamedItem for behaviour concerning default values. */ ::method removeNamedItemNS use strict arg namespaceURI=.nil, localName node = .nil if (localName)~isA(.string) then do if node~namespaceURI==namespaceURI then node = self~namedMap~remove(localName) else node = .nil end return node /** Adds a xmlNode using its nodeName attribute. If a node with that name is already present in this map, it is replaced by the new one. Replacing a node by itself has no effect. @param arg - A xmlNode to store in this map, accessible using its nodeName attribute. @return node - The replaced xmlNode or .nil if no replacement. @raises user domException - WRONG_DOCUMENT_ERR @raises user domException - INUSE_ATTRIBUTE_ERR */ ::method setNamedItem use strict arg arg --if arg~ownerDocument<>self~ownerDocument -- then raise user domException description (.domException~wrong_document_err) if arg~nodeType==.xmlNode~attributeNode then do if arg~ownerElement<>.nil then raise user domException description (.domException~inuse_attribute_err) end node = .nil if arg~isA(.xmlNode) then do name = arg~nodeName node = self~namedMap[name] self~namedMap[name] = arg end return node /** Adds a node using its namespaceURI and localName. If a node with that namespace URI and that local name is already present in this map, it is replaced by the new one. Replacing a node by itself has no effect. @param arg - A node to add to the map, subsequently accessible via namespaceURI and localName. @return node - The replaced xmlNode or .nil if no replacement. @raises user domException - WRONG_DOCUMENT_ERR @raises user domException - INUSE_ATTRIBUTE_ERR */ ::method setNamedItemNS use strict arg arg if arg~ownerDocument<>self~ownerDocument then raise user domException description (.domException~wrong_document_err) if arg~nodeType==.attributeElement then do if arg~ownerElement<>.nil then raise user domException description (.domException~inuse_attribute_err) end node = .nil if arg~isA(.xmlNode) then do name = arg~localName node = self~namedMap[name] -- the following replaces also a node from a different namespace -- probably need a directory with name indexes and items of a directory with namespace indexes and node items if node~namespaceURI<>arg~namespaceURI then node = .nil else self~namedMap[name] = arg end return node /** Provides a xmlNamedNodeMap as a native ooRexx directory @return directory - A native ooRexx directory representing the NamedNodeMap. */ ::method toOorexxDirectory return self~namedMap /** Sets a NamedNodeMap from a native ooRexx directory @param nodeDirectory - The native ooRexx directory to replace an existing xmlNamedNodeMap. @raises syntax 93.914 - Named item is not a proper xmlNode */ ::method fromOorexxDirectory use strict arg nodeDirectory s = nodeDirectory~supplier do while s~available if \s~item~isA(.xmlNode) then do raise syntax 93.914 array (nodeDirectory, .xmlNode) end s~next end self~namedMap = nodeDirectory return /* :end */ /* CLASS: xmlAttr */ /** The xmlAttr interface represents an attribute in an xmlElement object. Typically the allowable values for the attribute are defined in a schema associated with the document. xmlAttr objects inherit the xmlNode interface, but since they are not actually child nodes of the element they describe, the DOM does not consider them part of the document tree. Thus, the xmlNode attributes parentNode, previousSibling, and nextSibling have a .nil value for xmlAttr objects. The DOM takes the view that attributes are properties of elements rather than having a separate identity from the elements they are associated with; this should make it more efficient to implement such features as default attributes associated with all elements of a given type. Furthermore, xmlAttr nodes may not be immediate children of a xmlDocumentFragment. However, they can be associated with xmlElement nodes contained within a xmlDocumentFragment. In short, users and implementors of the DOM need to be aware that xmlAttr nodes have some things in common with other objects inheriting the Node interface, but they also are quite distinct. The attribute's effective value is determined as follows: if this attribute has been explicitly assigned any value, that value is the attribute's effective value; otherwise, if there is a declaration for this attribute, and that declaration includes a default value, then that default value is the attribute's effective value; otherwise, the attribute does not exist on this element in the structure model until it has been explicitly added. Note that the xmlNode nodeValue attribute on the xmlAttr instance can also be used to retrieve the string version of the attribute's value(s). If the attribute was not explicitly given a value in the instance document but has a default value provided by the schema associated with the document, an attribute node will be created with specified set to false. Removing attribute nodes for which a default value is defined in the schema generates a new attribute node with the default value and specified set to false. If validation occurred while invoking the xmlDocument normalizeDocument, attribute nodes with specified equals to false are recomputed according to the default attribute values provided by the schema. If no default value is associate with this attribute in the schema, the attribute node is discarded. In XML, where the value of an attribute can contain entity references, the child nodes of the xmlAttr node may be either xmlText or xmlEntityReference nodes (when these are in use; see the description ofxml EntityReference for discussion). */ ::class xmlAttr public subclass xmlNode /** Returns whether this attribute is known to be of type ID (i.e. to contain an identifier for its owner element) or not. When it is and its value is unique, the ownerElement of this attribute can be retrieved using the xmlDocument getElementById method. The implementation could use several ways to determine if an attribute node is known to contain an identifier:
If you feel inclined to make corrections, suggestions etc., please mail me any.
All content © Ruurd Idenburg, 2007–, except where marked otherwise. All rights reserved. This page is primarily for non-commercial use only. The Idenburg website records no personal information and sets no ‘cookies’. This site is hosted on a VPS(Virtual Private System) rented from Transip.nl, a Dutch company, falling under Dutch (privacy) laws (I think).

This page updated on by Ruurd Idenburg.