IBM®
Skip to main content
    Country/region select      Terms of use
 
 
   
     Home      Products      Services & solutions      Support & downloads      My account     

developerWorks  >  Lotus  >  Forums & community  >  Best Practice Makes Perfect

Best Practice Makes Perfect

A collaboration with Domino developers about how to do it and how to get it right in Domino

I've been doing some work recently that uses our LotusScript DOM classes, and I noticed what is probably not news to some of you, that apostrophes aren't correctly quoted when serializing from DOM, so that you can get something like this:

<thing description='Don't try this at home'>

This is of course not syntactically correct.

I have fixed the error, and future releases should not have this problem.

I also had occasion to want to insert a node in the middle of a list of sub-elements in the DOM structure, and this turned out to be harder to do than I thought it should be. I wrote the following subroutine, which does the trick, but it's not terribly efficient. Perhaps someone out there has a more ingenious technique.

Sub InsertNodeBefore(domdoc As NotesDOMDocumentNode, nodeSib As NotesDOMNode, nodeNew As NotesDOMNode)
        Dim parent As NotesDOMNode
        Set parent = nodeSib.ParentNode
        If parent.IsNull Then Error 18550, "Can't InsertNodeBefore node with no parent."
        Dim tempParent As NotesDOMNode
        Set tempParent = parent.Clone(False)
        Dim nodeNext As NotesDOMNode, nodeCur As NotesDOMNode
        Set nodeCur = nodeSib
        Do
                Set nodeNext = nodeCur.NextSibling
                tempParent.AppendChild nodeCur
                Set nodeCur = nodeNext
        Loop Until nodeCur.IsNull
       
        parent.AppendChild nodeNew
        Set nodeCur = tempParent.FirstChild
        Do
                Set nodeNext = nodeCur.NextSibling
                parent.AppendChild nodeCur
                Set nodeCur = nodeNext
        Loop Until nodeCur.IsNull
End Sub

Andre Guirard | 28 August 2007 02:27:44 PM ET | Plymouth, MN, USA | Comments (7)


 Comments

1) DOM for output, making it better
Kerr | 8/29/2007 9:43:06 AM

Hurm... What is NotesDOMDocumentFragmentNode used for? From reading the docs it can't actually appear in the DOM tree itself. So what happens if you do this:

nodeFrag=notesDOMDocumentNode.CreateDocumentFragmentNode()

nodeFrag.append(nodeNew)

nodeFrag.append(nodeSib)

parent.replaceChild(fragment, nodeSib)

will the the contents of the frag be direct children of the parent? When you append nodeSib to nodeFrag is it detached from the original parent? If so, would it work if you cloned nodeSib?

I might have a go at answering some of those questions if I get some time.

2) DOM for output, making it better
Kerr | 8/29/2007 2:28:56 PM

Well, the basic idea seems to work, though you do need ot clone the sibling.

Sub InsertNodeBefore(domdoc As NotesDOMDocumentNode, nodeSib As NotesDOMNode, nodeNew As NotesDOMNode)

Dim parent As NotesDOMNode

Set parent = nodeSib.ParentNode

If parent.IsNull Then Error 18550, "Can't InsertNodeBefore node with no parent."

Dim cloneSib As NotesDOMNode

Dim nodeFrag As NotesDOMDocumentFragmentNode

Set nodeFrag=domdoc.CreateDocumentFragmentNode()

Call nodeFrag.AppendChild(nodeNew)

Set cloneSib= nodeSib.clone(True)

Call nodeFrag.AppendChild(cloneSib)

Call parent.ReplaceChild(nodeFrag, nodeSib)

End Sub

Man, it's ages since I've done any LotusScript. Uurghh!!

3) DOM for output, making it better
Kerr | 9/7/2007 10:42:25 AM

I've had a nagging doubt about this andI've worked out what it was; the deep clone of the sibling could be quite a heavy operation.

This is a version that avoids the deep clone. One one extra line of code.

Sub InsertNodeBefore3(domdoc As NotesDOMDocumentNode, nodeSib As NotesDOMNode, nodeNew As NotesDOMNode)

Dim parent As NotesDOMNode

Set parent = nodeSib.ParentNode

If parent.IsNull Then Error 18550, "Can't InsertNodeBefore node with no parent."

Dim cloneSib As NotesDOMNode

Dim nodeFrag As NotesDOMDocumentFragmentNode

Set nodeFrag=domdoc.CreateDocumentFragmentNode()

Call nodeFrag.AppendChild(nodeNew)

Set cloneSib= nodeSib.clone(False)

Call nodeFrag.AppendChild(cloneSib)

Call parent.ReplaceChild(nodeFrag, nodeSib)

Call parent.ReplaceChild(nodeSib, cloneSib)

End Sub

4) I wouldn’t lose the deep clone...
Stan Rogers | 9/14/2007 6:52:59 AM

Yes, it may be "expensive", but if you do a simple (shallow) clone, you lose the descendant nodes. In something as simple as a rich text paragraph, that means that you lose any contained font elements, text runs, etc., making the function rather less than usefull.

5) I wouldn’t lose the deep clone...
Kerr | 9/16/2007 11:55:57 AM

Yes Stan, that's why it was there in the first place. But if you run the second version you will find that I don't loose anything. I use the shallow clone as a place holder, but since I never drop the reference to the deep cone, I then re-attach it back where I put the place holder. So I maintain everything, but don't have to do a deep clone.

6) I wouldn’t lose the deep clone...
Kerr | 9/16/2007 7:05:55 PM

Oops, little mistake in that description. I should have said that I never drop the reference to the original node, with any descendants, which is evidentially re-attached.

7) Thank you very much
sheponion | 5/15/2014 12:54:02 PM

Thank you - This is exactly what I was looking for and it works very well!

 Add a Comment
Subject:
   
Name:
Comment:  (No HTML - Links will be converted if prefixed http://)
 
Remember Me?     Cancel

Search this blog 

Disclaimer 

    About IBM Privacy Contact