bmx-ng / text.mod

Text Utilities
0 stars 3 forks source link

[xml.mod] Add TxmlNode.findPath:TxmlNode(path) #8

Open GWRon opened 1 year ago

GWRon commented 1 year ago

Am not sure if I use it right ... as the returned nodes look a bit empty sometimes.

Might be something the mxml code does not right already (or does right but I just do not understand it ...).

SuperStrict

Framework Text.XML
Import Brl.StandardIO

Local xml:String = "<?xml version=~q1.0~q?><rootnode><hello><world value=~qtest~q>how are you?</world></hello></rootnode>"
Local doc:TxmlDoc = TxmlDoc.readDoc(xml)
Local rootNode:TxmlNode = doc.getRootElement()
Print "root: " + rootNode.getName() 'prints rootnode

Local pathNode:TxmlNode 

'find first "<hello>"
pathNode= rootNode.FindPath("hello")
If pathNode Then Print "pathNode: " + pathNode.getName() + "  content="+ pathNode.GetContent()

'find first "<world>" which is child of "<hello>"
pathNode = rootNode.FindPath("hello/world")
If pathNode Then Print "pathNode: " + pathNode.getName() + "  content="+ pathNode.GetContent()

'find first "<world>" regardless of parent
pathNode = rootNode.FindPath("*/world")
If pathNode Then Print "pathNode: " + pathNode.getName() + "  content="+ pathNode.GetContent()

Print "."
Print "basic tree:"
For Local node:TxmlNode = EachIn rootNode.GetChildren()
    Print "root.child = " + node.getName() + "  content="+node.GetContent()
    For Local subNode:TxmlNode = EachIn node.GetChildren()
        Print "  node.child = " + subNode.getName() + "  content="+subNode.GetContent()
    Next
Next

Output:

Executing:mxml.findpath.debug
root: rootnode
pathNode: hello  content=how are you?
pathNode:   content=
pathNode:   content=
.
basic tree:
root.child = hello  content=how are you?
  node.child = world  content=how are you?

Process complete
GWRon commented 1 year ago

Tried with a more "standard" example xml:

mxml.findpath.xml:

<?xml version="1.0"?>
<articles>
    <article>
        <title>Text by John</title>
        <author>John</author>
    </article>
    <article>
        <title>Text by Jane</title>
        <author>Jane</author>
    </article>
</articles>

mxml.findpath.bmx:

SuperStrict

Framework Text.XML
Import Brl.StandardIO

Local doc:TxmlDoc = TxmlDoc.parseFile("mxml.findpath.xml")
Local rootNode:TxmlNode = doc.getRootElement()
Print "root: " + rootNode.getName() 'prints rootnode

Local pathNode:TxmlNode 

'find first "<article>" which is child of root ("<articles>")
'pathNode = rootNode.FindPath("article")

'find first "<author>"
pathNode = rootNode.FindPath("*/author")
If pathNode 
    Print "pathNode: " + pathNode.getName() + "  content="+ pathNode.GetContent()
    For Local node:TxmlNode = EachIn pathNode.GetChildren()
        Print "pathNode.child = " + node.getName() + "  content="+node.GetContent()
    Next
EndIf

Print "----------"

'using FindElement to return first article
pathNode = rootNode.FindElement("article")
If pathNode 
    Print "pathNode: " + pathNode.getName() + "  content="+ pathNode.GetContent()
    For Local node:TxmlNode = EachIn pathNode.GetChildren()
        Print "pathNode.child = " + node.getName() + "  content="+node.GetContent()
    Next
EndIf
Executing:mxml.findpath.debug
root: articles
pathNode:   content=
----------
pathNode: article  content=
        Text by John
        John

pathNode.child = title  content=Text by John
pathNode.child = author  content=John

Process complete

Either mxml implements it different to my assumption - or my (PR-)code is wrong

GWRon commented 1 year ago
mxml_node_t * bmx_mxmlFindPath( mxml_node_t * node, BBString * path) {
    char * p = 0;

    if (path != &bbEmptyString) {
        p = bbStringToUTF8String(path);
    }

    mxml_node_t * result = mxmlFindPath(node, p);

    //DEBUG output
    if (result != NULL) {
        char * n = mxmlGetElement(result);
        printf("mxmlFindPath(node=%p, name=\"%s\"  path=\"%s\")\n", node, n ? n : "no name", p ? p : "(null)");
        printf("text: %s\n", mxmlGetText(result,0));
        bbMemFree(n);
    }

    bbMemFree(p);

    return result;
}

outputs (for the findPath part):

Executing:mxml.findpath.debug
root: articles
mxmlFindPath(node=0xde5660, name="no name"  path="article/*/author")
text: (null)
pathNode:   content=

This looks to me as if ... mxml does something different, not my code.