GoogleIt Mail IT Print IT PermaLinkSome Useful Utility Functions For Processing XML/DOM In JavaScript01:23:14 PM
Written By : Richard SchwartzCategory : AJAX
Location : Nashua, NH

If you happened to have looked into the source of my ajax crypto proof of concept, you may have seen a set of utility functions that I use for walking through the XML DOM returned by the ?ReadViewEntries URL. These are actually JavaScript versions -- almost verbatim except for language syntax -- of routines I have been using in LotusScript for several years (e.g., as part of my bloggregator code). They're an example of something I often do: wrapping lower-level functionality of an API into slightly higher-level routines that meet the requirements for a particular coding pattern that I'm used to. Domino programmers will certainly notice something familiar in the names of my functions "getFirstElement()", "getLastElement()", "getNthElement()" and even "getElementText()". As it turns out, these functions turn out to be quite a bit more useful than I had expected, because they (quite accidentally) hide some of the differences between DOM implementations that you will find in Firefox and IE.


Here's the code. I plead guilty to not commenting it, but then again JavaScript comments are lost bandwidth, aren't they?


function getFirstElement(node,elementName) {
    
    child =  node.firstChild;
    while (  child != null ) {
        if (child.nodeType == 1) {
            if ( child.nodeName == elementName) {
                return child;
            }
        }    
        child = child.nextSibling;    
    }
    return null;    
}


function getLastElement(node,elementName) {
    
    child =  node.lastChild;
    while (  child != null ) {
        if (child.nodeType == 1) {
            if ( child.nodeName == elementName) {
                return child;
            }
        }    
        child = child.previousSibling;    
    }
    return null;    
}



function getNthElement(node, elementName, n) {
        
    foundCount = 0;
    child =  node.firstChild;    
    while (child != null)  {
        if (child.nodeType == 1) {
            if (child.nodeName == elementName) {
                foundCount = foundCount + 1;
                if (foundCount == n) {        
                    return child;        
                }
            }
        }
        child = child.nextSibling
    }
    
    return null;    
}

function getElementText(node) {
        
    if (node == null) {
        return("");
    }
    
    child =  node.firstChild;
    foundCDATA = false;
    foundPlainText = false;
    
    while (child != null) {    
        if (child.nodeType == 4) {            // CDATA node
            result = child.nodeValue;
            foundCDATA = true;
        }
        else {
            if (child.nodeType == 3) {        // Text node
                result = child.nodeValue;
                foundPlainText = true;
            }
        }
        if (foundCDATA == true) {
            return result
        }    
        child = child.nextSibling    
    }
    if (foundPlainText == false) {
        return("")
    }

    return result;
}


getFirstElement() takes two arguments: a node in an XML DOM tree, and the name of a desired child node. It returns the first child node with that name. As it turns out, DOM implementations might not always return nodes in the same order if you simply call node.firstChild() and node.nextSibling(), so my decision to write a wrapper function that assumes you have to loop through child nodes to find the first node of a given type pays off. The node returned by firstChild() might turn out not to be what you expect it to be, so a looping search guarantees that you will get what you want.


getLastElement() and getNthElement() are simple enough variations on getFirstElement(), so I won't bother to explain them. Let's move on to getElementText().


The motivation for getElementText() was to be able to handle either a simple text node or a CDATA node. It looks through through children of a given node, finding either text or CDATA, and returns whichever it finds, or an empty string if neither is found. In most cases, I simply don't care whether or not the creator of the XML has put text inside a CDATA section or not. I don't want to dictate that CDATA must be used if it's not necessary, but I want to accomodate it if it was necessary. In either case, I just want the text. This function takes care of that for me.

1588 .
Comments :v

1. Stan Rogers05/19/2005 06:18:57 PM
Homepage: http://stanrogers.blogspot.com


Ah, I see you found the "nodes between the nodes". Ain't they a pain?




2. Richard Schwartz05/19/2005 09:05:46 PM
Homepage: http://smokey.rhs.com/web/blog/PowerOfTheSchwartz.nsf


Yep!

-rich




3. 08/02/2005 11:59:10 AM


Damn, that's exactly the function I was trying to write!
Thanks!

By the way, this 'Live Preview' this really sucks in IE!!!
...flashing ...page shifting ...getting sick




4. Richard Schwartz08/02/2005 12:07:19 PM
Homepage: http://www.rhs.com/poweroftheschwartz


Oh! You're so right. Yuck. Something in the css is really mucking it up! I'll look into it.

-rich




5. Jack Ratcliff08/12/2005 10:32:43 PM
Homepage: http://jackratcliff.com


AWESOME! AWESOME! AWESOME!

Rich, I just ran into this problem last week. Thanks for saving me the work of having to write these myself!

Jack




Enter Comments^


Email addresses provided are not made available on this site.





You can use UUB Code in your posts.

[b]bold[/b]  [i]italic[/i]  [u]underline[/u]  [s]strikethrough[/s]

URL's will be automatically converted to Links


:-x :cry: :laugh: :-( :cool: :huh: :-) :angry: :-D ;-) :-p :grin: :rolleyes: :-\ :emb: :lips: :-o
bold italic underline Strikethrough





Remember me    

Never Underestimate The Power Of The Schwartz
Yellow Is The New Black
Don't Panic Links
Contact Me
CloseSidebars.gif
Story Calendar
July 2008
Su
Mo
Tu
We
Th
Fr
Sa
1
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Lotus Domino ND6 RSS News Feed RSS Comments Feed Blog Admin Lotus Geek OpenNTF BlogSphere
Monthly Archive
Stories By Category
Responses Elsewhere
Life, The Universe, And Everything Else