Parse strings in any XML format
Implement a function, write a program, and convert any XML-formatted string into a %XML.Adaptor object without having to create a Moudle class. This makes it easier to work with XML data. How to write it;
Comments
You cannot convert an arbitrary XML string directly into a %XML.Adaptor object without a class definition that represents the XML structure. The available material shows that %XML.Reader works together with %XML.Adaptor, but you must first define a class that extends %XML.Adaptor and matches the XML structure, then correlate the XML root or element to that class and read it. [1][2]
A typical pattern is:
Class MyApp.Messages.PatientXML Extends (%Persistent, %XML.Adaptor)
{
Parameter XMLNAME = "Patient";
Property PatientID As %String;
Property PatientName As %String;
Property Age As %String;
Property DateOfBirth As %String;
Property Sex As %String;
Property PatientClass As %String;
Property AssignedPatientLocation As %String;
Property AttendingDoctor As %String;
ClassMethod XMLToObject(xmlStream As %Stream.Object = "", xmlString, filename = "C:\learn\hl7msg\test.xml")
{
Set reader = ##class(%XML.Reader).%New()
If filename'="" {
Set sc=reader.OpenFile(filename)
}
ElseIf $IsObject(xmlStream){
Set sc=reader.OpenStream(xmlStream)
}
ElseIf xmlString'="" {
Set sc=reader.OpenString(xmlString)
}
Else {
Return $$$ERROR("No file name,string or stream found")
}
If $$$ISERR(sc) Do $system.OBJ.DisplayError(sc) Quit
Do reader.CorrelateRoot($classname())
Do reader.Next(.patient,.sc)
If $$$ISERR(sc) Do $system.OBJ.DisplayError(sc) Quit
ZWrite patient
}
}
The more general import flow is:
- Create a
%XML.Readerinstance. - Open the XML from a file, stream, or string.
- Associate an XML element with a class by using
Correlate()orCorrelateRoot(). - Call
Next()to instantiate and populate the object. [1][2]
Example:
Set reader = ##class(%XML.Reader).%New()
Set sc = reader.OpenString(xml)
Do reader.Correlate("resultado","EsquemasDatos.Radiologia.Resultado")
Do reader.Next(.ReturnObject,.sc)
This returns an object of the correlated class. [3][4]
If your goal is specifically to handle any XML dynamically without creating a predefined class, the suitable option shown is EnsLib.EDI.XML.Document, not %XML.Adaptor. It allows runtime and XPath-based access to XML content without requiring a predefined schema or class. [1]
Example:
ClassMethod ParseXML(xmlfile As %String="")
{
Set ediXMLDoc = ##class(EnsLib.EDI.XML.Document).ImportFromFile(xmlfile,,.sc)
If $$$ISERR(sc) {
Quit
}
Write ediXMLDoc.GetValueAt("/Patient/PatiendID")
}
So the answer is:
- If you want a
%XML.Adaptorobject, you need a matching class definition. [1][2] - If you do not want to create classes and need to parse arbitrary XML, use
EnsLib.EDI.XML.Documentfor dynamic access instead. [1]
Sources: