Open GWRon opened 5 years ago
xml.bmx - TxmlNode add:
Rem
bbdoc: Get the first child node with the given path
about:
(From the mxml-docs:) The first child node of the found node is
returned if the given node has children and the first child is a
value node.
returns: node or null
End Rem
Method FindPath:TxmlNode(path:String)
return TxmlNode._create(bmx_mxmlFindPath(nodePtr, path))
End Method
glue.c add:
mxml_node_t * bmx_mxmlFindPath( mxml_node_t * top, BBString * path) {
char * charPath = bbStringToUTF8String(path);
mxml_node_t * node = mxmlFindPath(top, charPath);
bbMemFree(charPath);
return node;
}
common.bmx add to extern block:
Function bmx_mxmlFindPath:Byte Ptr(top:Byte Ptr, path:String)
Tested it and it works - results looked odd at first until I've read that the first child-value is returned if there are children - so GetContent()
returns only the first child node-text instead of the whole mess. This seems to be "intented"
xml.bmx - TxmlNode add:
Rem
bbdoc: Find the named element.
about:
(From the mxml-docs:) The search is constrained by the name,
attribute name, and value; any NULL names or values are treated as
wildcards, so different kinds of searches can be implemented by
looking for all elements of a given name or all elements with a
specific attribute. The descend argument determines whether the
search descends into child nodes; normally you will use
MXML_DESCEND_FIRST for the initial search and MXML_NO_DESCEND to
find additional direct descendents of the node. The top node
argument constrains the search to a particular node's children.
returns: node or null
End Rem
Method FindElement:TxmlNode(top:TxmlNode, element:string = "", attr:string = "", value:string = "", descend:Int = -1)
'descend = -1 equals to MXML_DESCEND_FIRST
If top
return TxmlNode._create(bmx_mxmlFindElement(nodePtr, top.nodePtr, element, attr, value, descend))
Else
return TxmlNode._create(bmx_mxmlFindElement(nodePtr, 0, element, attr, value, descend))
End If
End Method
glue.c add:
mxml_node_t * bmx_mxmlFindElement(mxml_node_t * node, mxml_node_t * top, BBString * element, BBString * attr, BBString * value, int descend) {
char * charElement = bbStringToUTF8String(element);
char * charAttr = bbStringToUTF8String(attr);
char * charValue = bbStringToUTF8String(value);
if (charElement && !charElement[0]) { charElement = NULL; }
if (charAttr && !charAttr[0]) { charAttr = NULL; }
if (charValue && !charValue[0]) { charValue = NULL; }
mxml_node_t * foundNode = mxmlFindElement(node, top, charElement, charAttr, charValue, descend);
bbMemFree(charElement);
bbMemFree(charAttr);
bbMemFree(charValue);
return foundNode;
}
common.bmx add to extern block:
Function bmx_mxmlFindElement:Byte Ptr(node:Byte Ptr, top:Byte Ptr, element:string, attr:string, value:string, descend:Int)
It compiles - but I miss something (either in my initial call or the code) as it just does not find a node. I also tried to set the passed params to "NULL" in case of empty strings being interpreted differently. Also passing "NULL" directly to the function (as if my code was not doing what it should) did not find the "element".
@woollybah
Do you see any flaws in the mxmlFindElement()
as it does not what it should (= what I planned it should do ;-)).
I've got an implementation of it working, which I'll commit now.
I dropped top
and descend
args :-)
You might add findPath
too.
Or... Wait until Pull Request later this evening (will do as you did...with bbnullstring and so on).
Hmm checked your (and mine) "FindElement" - and ... it seems that the mxml function returns the first "inner" node.
I have a function to search for "child elements by name" - as soon as the node.getName()
corresponds to a given string, this node is returned.
Outputting ToString()
or GetContent()
of this node includes the whole node code itself (eg. <test>string<children>string</children></test>
and the content being "stringstring").
Using "FindElement" or "FindPath" results in an empty ToContent()
and a "string" for ToString()
.
BUT ... if I replace FindElement(...).ToString()
with FindElement(...).GetParent().ToString()
(or GetContent
) I receive the same output than with my custom function.
So it seems as if those both functions do not return the desired node - but a subsequent one (maybe some "inner node" or so).
Regarding my last comment: mxmlFindPath()
documentation states this "odd" behaviour:
The first child node of the found node is returned if the given node has children and the first child is a value node.
https://www.msweet.org/mxml/mxml.html#mxmlFindPath
Interestingly this is not annotated for mxmlFindElement
.
Low priority:
libXML has some pretty mighty xpath functionality - but mxml provides a simple approach to fetch and find nodes too:
mxmlFindPath()
andmxmlFindElement()
.Might be a good idea to expose them to brl.xml too.