Article Gevorg Arutiunian · Dec 27, 2018 2m read

Use %XML.Node to walk a DOM

The following code walks a DOM using %XML.Node. It also prevents %XML.Writer to change whitespace. Run the code using the class method "test":


Class objectscript.walkDOM Extends %Persistent
{
ClassMethod dfs(node As %XML.Node)
{
s entrynode=node.NodeId
do {
//element nodes with one whitespacetyped child are the ones we want to change
if (node.NodeType=$$$xmlELEMENTNODE){
s snode=node.NodeId
if (node.MoveToFirstChild())
{ i ('node.MoveToNextSibling()){ i (node.NodeType=$$$xmlWHITESPACENODE){ s node.NodeType=$$$xmlTEXTNODE s node.NodeId=snode } } } s node.NodeId=snode
}
if (node.HasChildNodes()){ d node.MoveToFirstChild() d ..dfs(node) } } while (node.NodeType'="" && node.MoveToNextSibling()) s node.NodeId=entrynode

}
 
ClassMethod test()
{
  set xml = "abcdefg"
 
  s reader=##class(%XML.Reader).%New()
  do reader.OpenString(xml)  
  set writer = ##class(%XML.Writer).%New()
  //do some magic
  d ..dfs(reader.Document)
   
  w !,"with indent=1:",!
  set writer.Indent = 1
  do writer.OutputToString()
  do writer.Document(reader.Document)
  w writer.GetXMLString()
  set writer.Indent = 0
  w !,"with indent=0:",!
  do writer.OutputToString()
  do writer.Document(reader.Document)
  w writer.GetXMLString()
}

}

Here's a link to the code on GitHub: https://github.com/intersystems-community/code-snippets/blob/master/src/cls/objectscript/walkDOM.cls