Archived Forum Post

Index of archived forum posts

Question:

ChildContentMatches? Locating matching xml nodes

Jun 11 '12 at 22:56

Ok, so I have a requirement to locate xml nodes with specific details. Here's an example:

<object> <name>"test name"</name> </object>

Of course it's a simplified example, but what I'd like to do is put in some sort of wildcard details, for instance "test*", and get back a node collection with all the matching objects.

Is this something I can do readily using just the API?

Thanks!


Answer

There is no method to return a collection of nodes. Here is a simple C++ code example that demonstrates how to traverse any XML document. It does not use recursion -- because recursion can blow the stack.

void xmlTraverseDoc(void)
    {
    CkXml xml;

    bool success = xml.LoadXmlFile("c:/aaworkarea/xmp.xml");
    if (!success)
    {
    printf("%s\n",xml.lastErrorText());
    return;
    }

#define MAX_MATCHES 10000

    CkXml **matched = new CkXml *[MAX_MATCHES+1];
    int numMatches = 0;

#define STACK_SIZE 10000

    // Don't use recursion because it could blow the stack.
    // Instead keep a stack manually.
    CkXml **stack = new CkXml *[STACK_SIZE+1];
    int stackIdx = 0;

    // Prime the stack with the root node.
    stack[stackIdx++] = xml.GetSelf();

    bool bCaseSensitive = false;

    while (stackIdx)
    {
    // Pop the stack.
    CkXml *px = stack[--stackIdx];

    // Put the child nodes on the stack.
    int numChildren = px->get_NumChildren();
    for (int i=0; i<numChildren; i++)
        {
        if (stackIdx < STACK_SIZE) stack[stackIdx++] = px->GetChild(i);
        }

    // Does this node match?
    if (px->ContentMatches("test*",bCaseSensitive) &&
        (numMatches < MAX_MATCHES))
        {
        // Yes, keep the match.
        matched[numMatches++] = px;
        }
    else
        {
        // Delete our reference.
        delete px;
        }

    }

    delete [] stack;

    int i;
    for (i=0; i < numMatches; i++)
    {
    delete matched[i];
    }

    delete [] matched;

    return;
    }