Question
Oliver Catling · Nov 27, 2020

How To Return A %XML.XPATH.DOMResult Into A String

Hi,

I am working with XML and I would like to be able to access parts of the XML document and return them as a string. I am building an XPath document then evaluating an expression on it which returns a list of DOMResult objects. After accessing one of the objects I would like to convert this to a string and am having difficulty in doing this. I originally went down the path of essentially creating my own parsing method that converts this to xml itself, but a collegue has pointed out I might be able to use the %XML.Writer class to do this. However, I am unable to find a way to pass a DOMResult into a writer class and then output to string. I have written a quick example of what I am trying to do:

ClassMethod testXmlToString()
{
set status ##class(%XML.XPATH.Document).CreateFromString("<a><b><c>some content</c></b></a>", .doc)
set status doc.EvaluateExpression("/a", "b", .field) obj field.GetAt(1)
set writer ##class(%XML.Writer).%New()
set status =  writer.OutputToString()
set status writer.DocumentNode(obj)
Set xmlString writer.GetXMLString(.sc) !, "xmlString="_xmlString
QUIT xmlString
}

We're running Ensemble 2015.2
If anybody can lend hand it would be greatly appreciated.
 

00
0 0 4 62

Replies

Examining an XML Subtree

  try{

    $$$ThrowOnError(##class(%XML.XPATH.Document).CreateFromString("<a><b><c>some content</c></b></a>", .doc))
    
$$$ThrowOnError(doc.EvaluateExpression("/a""b", .field))
    
#dim obj As %XML.XPATH.DOMResult field.GetAt(1)
    
    
while obj.Read() {
      
if obj.HasValue {
        
write obj.Path,": ",obj.Value,!
      
}
    }
    
  }
catch(ex){
    
write "Error "ex.DisplayString(),!
  
}

Result:
b\c: some content

Thanks for this, but im specifcally looking to recreate the xml in the string. So from the case above im looking to return a string like :

"<b><c>some content</b></c>"

As you're using Ensemble, you can use class EnsLib.EDI.XML.Document. I don't have version 2015, but the following works on IRIS. I hope this is present in Ensemble 2015 as well. (Note that, annoyingly, method domGetValueAt is marked internal, and therefore doesn't show up in the documentation. I don't know how to achieve the same result without using this method.)

Set XML = "<a><b><c>some content</c></b></a>"
Set Path = "/a/b"
Set Doc = ##class(EnsLib.EDI.XML.Document).ImportFromString(XML, .sc)
If 'sc Quit $System.Status.DisplayError(sc)
Set sc = Doc.domGetValueAt(.Value, Path, "fo", 1)
If 'sc Quit $System.Status.DisplayError(sc)
Write Value,!

This outputs "<b><c>some content</c></b>" as you want.

Hope this helps,
Gertjan.

Yes this does exactly what I am after - Thank you Gertjan!