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.
 

Comments

Vitaliy Serdtsev · Nov 27, 2020

Examining an XML Subtree

  try{

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

Result: b\c: some content
0
Oliver Catling  Nov 27, 2020 to Vitaliy Serdtsev

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>"

0
Gertjan Klein · Nov 27, 2020

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.

0
Oliver Catling  Nov 27, 2020 to Gertjan Klein

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

0