ColdFusion member functions for XML object management
Prior to ColdFusion 2018, ColdFusion supported the following XML member functions:
- .elemNew() (equivalent of XmlElemNew)
- .childPos() (equivalent of XmlChildPos)
- .duplicate() (equivalent of Duplicate)
- .getNodeType() (equivalent of XmlGetNodeType)
- .search() (equivalent of XmlSearch)
- .transform() (equivalent of XmlTransform)
Since ColdFusion also supports using array and structure functions to manage XML document objects, I filed CF-4199973 to add the relevant string, struct and array member functions on XML variables.
ColdFusion 2018 added the following XML member functions:
- * .append() (equivalent of StructAppend)
- ** .clear() (equivalent of ArrayClear and StructClear)
- * .count() (equivalent of StructCount)
- ** .delete() (equivalent of StructDelete)
- ** .deleteAt() (equivalent of ArrayDeleteAt)
- * .isEmpty() (equivalent of StructIsEmpty and ArrayIsEmpty()) .hasChild() (equivalent of not-yet-added XMLHasChild)
- * .len() (equivalent of ArrayLen)
- * .keyArray() (equivalent of StructKeyArray)
- * .keyList() (equivalent of StructKeyList)
- * .toString() (equivalent of ToString)
- * .update (equivalent of StructUpdate)
* – Covered by CF-4199973.
** – Pending in CF-4203285.
.clear() would seemingly be ambiguous, since ArrayClear() and StructClear() can both be used on an XML object. However, ArrayClear(xml) actually *deletes* nodes and its functionality is already covered by StructDelete() and ArrayDeleteAt(). ArrayClear(xmlFoo.xmlBar) deletes all nodes named ‘xmlBar’ under xmlFoo (equivalent of StructDelete(xmlFoo, “xmlBar”)). ArrayClear(xmlFoo.xmlBar) deletes the second node named ‘xmlBar’ under xmlFoo (equivalent of ArrayDeleteAt(xmlFoo.xmlBar, 2)). So, xmlObject.clear()/XMLClear(xmlObject) should be added to cover StructClear(xmlObject)’s functionality. StructClear(xmlFoo.xmlBar) and StructClear(xmlFoo.xmlBar) clear (convert to empty node) the first node named ‘xmlBar’ under xmlFoo. ArrayClear() Repro: https://trycf.com/gist/49487fe7e971236bafe0a6685374ca86/acf2018?theme=monokai. StructClear() Repro: https://trycf.com/gist/e04db3702a5bdbbe06de6896639452c5/acf2018?theme=monokai.
No equivalent for StructDelete() was added. StructDelete(xmlFoo, “xmlBar”) deletes all nodes named ‘xmlBar’ under xmlFoo. So, xmlObject.delete(childName)/XMLDelete(xmlObject, childName) should be added to cover StructDelete(xmlObject, childName)’s functionality. Repro: https://trycf.com/gist/493f0ae6ba00a7d2b528394fa36a1898/acf2018?theme=monokai.
No equivalent for ArrayDeleteAt() was added. ArrayDeleteAt(xmlFoo.xmlBar, 2) deletes the second node named ‘xmlBar’ under xmlFoo. So, xmlObject.deleteAt(position)/XMLDeleteAt(xmlObject, position) should be added to cover ArrayDeleteAt(xmlObject, position)’s functionality. Repro: https://trycf.com/gist/1aa6b58603f20739907bfa21ff540ff5/acf2018?theme=monokai.
Equivalent for Duplicate() exists in CF2016 for all data types. So, XMLDuplicate(xmlObject) does not need added. Repro: https://trycf.com/gist/87b44d40d3400dfa97b4d19911b58a07/acf2016?theme=monokai.
.isEmpty() was not added because .hasChild() makes more sense in the context of XML and because it would’ve been ambiguous, since ArrayIsEmpty() and StructIsEmpty() can both be used on an XML object. ArrayIsEmpty(xmlFoo.xmlBar) returns YES if xmlFoo contains any nodes named ‘xmlBar’. Whereas, StructIsEmpty(xmlFoo.xmlBar) returns YES if xmlBar contains any nodes. Repro: https://trycf.com/gist/9a73f736757625ecd6f6f9695c8fea65/acf2018?theme=monokai.
.hasChild() currently doesn’t work (always returns YES) and, if it did, only covers StructIsEmpty()’s functionality but not ArrayIsEmpty’s. So, xmlObject.hasChild([childName])/XMLHasChild(xmlObject[, childName]) needs an optional ‘childName’ parameter, in order to also cover ArrayIsEmpty(xmlObject.childName)’s functionality. Repro: https://trycf.com/gist/0db692627ccefdfbe436e756988c10c1/acf2018?theme=monokai.
No equivalent for Len() was added. Len(xmlObject) implicitly casts xmlObject to string and returns the string’s length. However, IMO, an equivalent XML member function for Len(xmlObject) does not need added since: 1) it’s undocumented functionality, 2) xmlObject.toString().len() covers its functionality and, more importantly IMO, 3) xmlObject.len() is needed to, and currently does, cover ArrayLen(xmlObject)’s functionality. Repro: https://trycf.com/gist/e0b20bf374a84f279f38974268813ec4/acf2018?theme=monokai.
ArrayLen(), like a few of the others, is not completely documented. ArrayLen(xmlFoo.xmlBar) counts the nodes named ‘xmlBar’ under xmlFoo. See Repro for Observation 7.
StructGet() does not support array notation when referencing an XML object. So, StructGet() needs fixed to support array notation when referencing an XML object. Repro: https://trycf.com/gist/baa6a4aeeec368e6567efe5cf827ee4c/acf2018?theme=monokai
Since ToString() is not XML-specific, the XMLToString(xmlObject) BIF does not need added.
Currently, xmlObject.update() returns a struct that doesn’t contain, for example, the updated xmlText. So, xmlObject.update() needs fixed to return the updated XML. Repro: https://trycf.com/gist/4031ebc027c788574948183387b56b68/acf2018?theme=monokai
The “Supported XML member functions” list isn’t, but should be, alphabetical. And it should consistently use ‘someVar’ like the other member function list tables. And the list’s purpose isn’t for showing syntax, so “xmlObject.update(String key, Object value)” should just be “someVar.update()”. And XmlLen/someVar.len() is missing and needs added. And .toString(), added to XML in CF2018, isn’t listed but should be. And .duplicate() also exists on XML, but isn’t listed and should be.
Once all the issues are fixed, the “Supported XML member functions” doc list should look like (w/ non-XML-specific at bottom):
# New in Adobe ColdFusion (2018 release)