I noticed this morning, while writing a utility that uses DXL to reverse the order of left and right frames in a frameset (for BIDI) that the representation for complex framesets, though it "round trips" successfully, is not structured as one might expect. For instance, consider the frameset shown on the right. We would expect the DXL to have a tree structure such as:
| 1. frameset | |||
| .... | a. frameset | ||
| .... | .... | i. frame A | |
| .... | .... | ii. frameset | |
| .... | .... | .... | x. frame B |
| .... | .... | .... | y. frame C |
| .... | b. frame D | ||
However, the actual structure is:
| 1. frameset | |||
| .... | a. frameset | ||
| .... | .... | i. frame A | |
| .... | .... | ii. frameset | |
| .... | .... | .... | x. frame B |
| .... | .... | .... | y. frame C |
| .... | .... | iii. frame D | |
A subtle but important difference -- frame D is a child of the wrong node.
The importer doesn't actually pay attention to the XML hierarchy in this case. Instead, it looks at the 'rows' or 'columns' attribute of a frameset element to determine how many children it has. That's why the round-trip works, and of course, if you wanted to manipulate the frameset in a way that doesn't depend on the structure (replacing a replica ID in links, for instance), it's not a problem. But if you're doing something where it does matter (as it does for my application), the workaround is to fix up the DOM tree using a routine such as the following:
' domeFS is a
' If it does not contain enough, error out. If it contains too many, the spares should be moved to
' the parent, which is assumed to be also a frameset. Process recursively.
' Note: this could be done without passing in the parent element, since it can be retrieved from
' domeFS. But passing Nothing for this argument on the initial iteration, lets you prevent
' a node being added as a child of a non-frameset node, without having to take the time in here
' to test whether the parent is a frameset node.
' This is to workaround a bug in the DXL exporter output, where frameset elements are not closed
' early enough.
Dim strElems$, cExpected%, values
strElems = domeFS.GetAttribute("rows")
If strElems = "" Then strElems = domeFS.GetAttribute("columns")
If strElems = "" Then
cExpected = 1
Else
values = Split(strElems, " ")
cExpected = 1+UBound(values)
End If
Dim domn As NotesDOMNode
Dim domeChild As NotesDOMElementNode
Set domn = domeFS.FirstChild
Do Until domn.Isnull
If domn.Nodetype = DOMNODETYPE_ELEMENT_NODE Then
Set domeChild = domn
Dim strNam$
strNam = domeChild.Nodename
If strNam = "frame" Or strNam = "frameset" Then
If strNam = "frameset" Then
FixupFrameset domeChild, domeFS
End If
If cExpected = 0 Then
domeFS.Removechild domeChild
parent.Appendchild domeChild
Else
cExpected = cExpected - 1
End If
End If
End If
Set domn = domn.Nextsibling
Loop
If cExpected > 0 Then
Error 13990, "Frameset contained fewer children than the columns or rows attribute indicates (" & strElems & ")."
End If
End Sub
Andre Guirard | 1 June 2009 01:03:37 PM ET | Home, Plymouth, MN, USA | Comments (1)

