Question
Lewis Houlden · Aug 17

Base64 payload and XML to objects

I am trying to import a large base64 string into objects but I can't seem to get it to work:

ClassMethod Test() As %Status
{
Set readerForItkRequestData = ##class(%XML.Reader).%New()
 
Set file="c:\Source\test_full.xml"
 
Set status = readerForItkRequestData.OpenFile(file)
Do readerForItkRequestData.Correlate("Envelope","Phu.Epro.Schema.Itk.Envelope")
set temp = readerForItkRequestData.Next(.pOutput,.tStatus)
Do pOutput.%Save()

}

The class I'm trying to project to: 

Class Phu.Epro.Schema.Itk.Payload Extends (%Persistent, %XML.Adaptor)
{

Parameter XMLIGNOREINVALIDTAG = 1;

Property ManifestItemId As %String(XMLNAME = "id", XMLPROJECTION = "attribute");

Property FileName As %String(XMLNAME = "filename", XMLPROJECTION = "attribute");

Property Test As %String(MAXLEN = "", XMLPROJECTION = "content");}

The error I get is:

Datatype validation failed for tag, payload (ending at line 40 character 36), with value:

Here's the xml trying to be imported, with the base64 stripped:

<payload filename="eaf7a956-f09e-43a0-9a20-95696dc5acac.pdf" id="binaryDocument">J....YNCg==</payload>

It's worth mentioning this is a collection. The Payloads can also be quite different (notice how the first one doesn't have "content" and is complex type:

<payload id="clinicalDocument">
    <ClinicalDocument xmlns="urn:hl7-org:v3" xmlns:npfitlc="NPFIT:HL7:Localisation" classCode="DOCCLIN" moodCode="EVN">
        <typeId extension="POCD_HD000040" root="2.16.840.1.113883.1.3"/>
        <custodian typeCode="CST">
        </custodian>
        <componentOf typeCode="COMP">
                        </componentOf>
        <component contextConductionInd="true" typeCode="COMP">
            <nonXMLBody classCode="DOCBODY" moodCode="EVN">
                <text mediaType="text/plain" representation="TXT">Refer to other payloads in this message for document content</text>
            </nonXMLBody>
        </component>
    </ClinicalDocument>
</payload>
<payload filename="eaf7a956-f09e-43a0-9a20-95696dc5acac.pdf" id="binaryDocument">J....YNCg==</payload>

. Any help would be appreciated!
 

Product version: IRIS 2019.1
0
0 154
Discussion (4)2
Log in or sign up to continue

After some testing, it would appear as soon as I add another node/object in, it throws the same error, as if I cannot have a mix of content and elements:

<payload id="clinicalDocument">
                    <ClinicalDocument>
                    </ClinicalDocument>
                </payload>
                <payload filename="eaf7a956-f09e-43a0-9a20-95696dc5acac.pdf" id="binaryDocument">temp</payload>

The tag you want to correlate is "payload", not "Envelope"

Hi @Mike Henderson 
Thanks for the reply, however, the snippet I provided was only a subset of a rather large XML file. I didn't provide all of it as it would have taken a long time to remove patient data. 

I have however solved the problem. The import doesn't like it when there are two of the same nodes with different structures. What you can do though is turn on XMLSEQUENCE, and the import will honour the exact order of the XML from what you've defined in the class. Here's a snippet of what I did:

Class Phu.Epro.Schema.Itk.Payloads Extends (%Persistent%XML.Adaptor)
{

Parameter XMLIGNOREINVALIDTAG = 1;

Property Count As %String(XMLNAME "count"XMLPROJECTION "attribute");

Property Payload As Phu.Epro.Schema.Itk.Payload(XMLNAME "payload");

Property PayloadWithBase64 As %GlobalCharacterStream(XMLNAME "payload");

Parameter XMLSEQUENCE = 1;  }

A word of caution - you can exhaust RAM when correlating a object with a collection like this. The pattern I use for collections of unknown size is to correlate the collection tag and loop over the items. If the collection parent (eg Envelope here) is also needed you can use XSL to reorganize the XML nodes to make it easier for the XML reader to iterate.