The XML Declaration, DTD Nodes, and SAX Errors in LotusScript
The navigation and content articles covered the DOM nodes you use every day. This one covers the tier you almost never touch — the XML declaration, the DOCTYPE, processing instructions, entities, notations — plus the SAX side’s one genuinely useful class, NotesSAXException. The honest theme: in the Domino LotusScript binding, this DTD/declaration tier is mostly a navigation layer, not a data layer. Several of these classes give you nothing beyond the base node members.
TL;DR
- The XML declaration (
<?xml version="1.0" encoding="UTF-8"?>) only appears in the tree if you setdomParser.AddXMLDeclNode = Truebefore parsing — then it’s theFirstChildof the document node, aNotesDOMXMLDeclNodewithVersion/Encoding/Standalone. - Processing instructions (
NotesDOMProcessingInstructionNode) give youTargetandData. Notations (NotesDOMNotationNode) give youPublicID/SystemID. - DocumentType, Entity, and EntityReference nodes expose no class-specific properties in this binding — you can detect them by
NodeTypeand navigate them, but the LS API doesn’t surface their DTD internals (Entities,Notations,Name,PublicID…). That’s a real gap vs. the W3C interface. NotesSAXExceptionis the payoff on the SAX side: “Represents information about errors and warnings which occur during SAX parsing,” withMessage,Row,Column,PublicID,SystemID. You receive it in theSAX_Error/SAX_FatalError/SAX_Warningevents.- All new with Release 6, not supported in COM.
Seeing the XML declaration
By default the parser drops the <?xml … ?> declaration. To get a NotesDOMXMLDeclNode, flip the AddXMLDeclNode flag on the parser before you parse — the docs say it makes the declaration’s “version, encoding, and standalone attributes… included in the resulting DOM tree in a NotesDOMXMLDeclNode object,” appearing as the FirstChild of the document node:
Dim domParser As NotesDOMParserSet domParser = session.CreateDOMParser(inStream, outStream)domParser.AddXMLDeclNode = True ' must be set BEFORE parsingdomParser.Process
Dim n As NotesDOMNodeSet n = domParser.Document.FirstChildDo Until n.IsNull Select Case n.NodeType Case DOMNODETYPE_XMLDECL_NODE ' 13 Dim decl As NotesDOMXMLDeclNode Set decl = n Print "version=" & decl.Version & " encoding=" & decl.Encoding & _ " standalone=" & decl.Standalone Case DOMNODETYPE_PROCESSINGINSTRUCTION_NODE ' 7 Dim pi As NotesDOMProcessingInstructionNode Set pi = n Print "PI target=" & pi.Target & " data=" & pi.Data End Select Set n = n.NextSiblingLoopForgetting AddXMLDeclNode = True is the number-one reason “my XMLDeclNode is never there” — the node simply isn’t generated otherwise.
The thin tier
The remaining declaration-tier classes are thin by design:
| Class | NodeType | What it actually gives you |
|---|---|---|
NotesDOMProcessingInstructionNode | 7 | Target, Data |
NotesDOMNotationNode | 12 | PublicID, SystemID |
NotesDOMDocumentTypeNode | 10 | inherited node members only |
NotesDOMEntityNode | 6 | inherited node members only |
NotesDOMEntityReferenceNode | 5 | inherited node members only |
The notable gap: NotesDOMDocumentTypeNode’s one-line description is “The list of entities that are defined for the document,” yet the LotusScript binding exposes no Entities, Notations, Name, PublicID, or SystemID accessor on it — unlike the W3C DocumentType interface it nominally maps to. In practice you only observe these nodes while walking a tree; you can branch on their NodeType and read NodeName/NodeValue, but you can’t introspect the DTD through them. Whether you even see entity-reference nodes (type 5) depends on the parser’s ExpandEntityReferences setting.
So unless you’re handling processing instructions (Target/Data) or reading the declaration (Version/Encoding), this tier is something you skip over in a Select Case, not something you mine for data.
NotesSAXException — where the error data lives
The SAX parser is the streaming alternative to DOM, and its one class worth a deep look is the exception. NotesSAXException — “Represents information about errors and warnings which occur during SAX parsing” — is where you finally get rich diagnostics: not just a message but the Row and Column where parsing went wrong, plus PublicID / SystemID. You don’t construct it; the SAX parser hands it to your event handlers:
Dim saxParser As NotesSAXParser ' module-level so events can bind
Sub RunSaxParse() Dim session As New NotesSession Dim inStream As NotesStream, outStream As NotesStream Set inStream = session.CreateStream : Call inStream.Open("c:\xml\in.xml") Set outStream = session.CreateStream : Call outStream.Open("c:\xml\saxlog.txt")
Set saxParser = session.CreateSAXParser(inStream, outStream) On Event SAX_Error From saxParser Call SaxError On Event SAX_FatalError From saxParser Call SaxError On Event SAX_Warning From saxParser Call SaxError Call saxParser.ProcessEnd Sub
Sub SaxError(Source As NotesSAXParser, Exception As NotesSAXException) Call Source.Output("row " & Exception.Row & " col " & Exception.Column & _ ": " & Exception.Message & Chr(10))End Sub(Adapted from the documented SAX event signatures — the official example writes each event to an output file.)
That Row/Column pair is the reason to use SAX (or to catch this exception) when you need to tell a user where their XML is malformed — the DOM parser’s failures are far less precise about location.
This is the third of three pieces on the Domino DOM node classes, after navigation and the content nodes.
What about Java and SSJS?
As with the rest of the Domino DOM family, there’s no lotus.domino counterpart to map to — Java and XPages reach for the standard org.w3c.dom interfaces (ProcessingInstruction, DocumentType, Notation, Entity) and the JAXP SAX classes (org.xml.sax.SAXParseException, which carries the same line/column data as NotesSAXException). So relatedJava and relatedSsjs stay empty. If anything, the W3C DocumentType interface is richer than the Domino one here — the gap noted above is specific to the LotusScript binding.