Projecting objects as XML - prevent close tag?
I'm trying to project a series of objects and nested objects to XML, and I'm having difficulties getting the XML representation exactly the way I need it to be. Here's what I'm working with, nothing complicated:
Class XMLTest Extends (%RegisteredObject, %XML.Adaptor)
{
Property Id As Id;
}
Class Id Extends (%RegisteredObject, %XML.Adaptor)
{
Property Value As%String (XMLPROJECTION = "attribute");
}By default it seem closing tags are used with all elements, as such:
<XMLTest><IdValue="D1949EE1-7D03-4666-9548-D1A949E10327"></Id></XMLTest>Whereas I need these elements represented with just the forward slash terminator:
<XMLTest>
<Id Value="D1949EE1-7D03-4666-9548-D1A949E10327"/>
</XMLTest>Is there a way to configure the XML writer to achieve this, or a property declaration I can use?
Another question I have is around the structure of the classes that are to be projected, rather than the above main snippet, is it possible to use XML projection declarations to define that a simple property is an element with attributes and values? This would be a lot more convenient than creating classes just to hold their attribute values. For example something like:
Class XMLTest Extends (%RegisteredObject, %XML.Adaptor)
{
Property Id As%String (XMLPROJECTION = "element", XMLATTRIBUTE = "value")
}Any help is much appreciated.
Thanks
Comments
According to the documentation, it's not possible exporting an object.
Edit: however, as pointed out by @Herman Slagman in the next post, it's indeed possible, I'm going to provide feedback to documentation team.
You can manually create the XML document using %XML.Writer, like:
set writer=##class(%XML.Writer).%New()
set writer.Indent=1set writer.NoXMLDeclaration=1set status=writer.OutputToDevice()
set status=writer.StartDocument()
set status=writer.RootElement("XMLTest")
set status=writer.Element("Id")
set status=writer.WriteAttribute("Attribute","D1949EE1-7D03-4666-9548-D1A949E10327")
set status=writer.EndElement()
set status=writer.EndRootElement()
set status=writer.EndDocument()The output of the above code is:
<XMLTest><IdAttribute="D1949EE1-7D03-4666-9548-D1A949E10327"/></XMLTest>Having said that, what's your issue with the closing tag? Semantically there is no difference, any system should be able to handle both cases (with or without closing tag).
As for the documentation, we received your feedback item but due to an short term mishap lost your email address. Here's our reply:
Hello!
Thanks for providing feedback on InterSystems documentation. We make ongoing improvements to our content and really appreciate receiving input.
Regarding your feedback about writing an empty self-closing XML element, we have corrected the documentation. (I dug out my old test code and proved it to myself.)
We hope this addresses your input, and please feel free to be in touch if you have any follow-up questions or comments.
Sincerely,
InterSystems Documentation
It seems that both classes need to have the
parameter XMLUSEEMPTYELEMENT = 1;
But I am curious why you want to enforce it. Both forms are perfectly valid XML.
That's perfect thank you. To answer your and Enrico's question - I'm working against a FHIR spec and series of examples which present it in this way, so to avoid any potential problems I'm trying to match these as much as possible. It may be valid XML but I'm not taking any chances!
The XML & SOAP APIs are full of overrides for scenarios where some application or other is finicky.