Question
· Nov 7, 2023

XMLMessage XPath Evaluation problems

Hello,

 

I've been stuck on this for a few days so I figured I'd ask for help here.

 

I have an XMLMessage response from a ProvideAndRegister call which looks like this:

<?xml version="1.0" ?>
<!-- type: HS.Message.XMLMessage  id: ### -->
<XMLMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:s="http://www.w3.org/2001/XMLSchema">
  <ContentStream>
    <RegistryResponse xmlns="urn:oasis:names:tc:ebxml-regrep:xsd:rs:3.0" status="urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Failure">
      <RegistryErrorList highestSeverity="urn:oasis:names:tc:ebxml-regrep:ErrorSeverityType:Error">
        <RegistryError codeContext="Document status urn:uuid:abcdef12-3456-7890-abcd-ef1234567890 not Approved" errorCode="XDSRegistryDeprecatedDocumentError" location="" severity="urn:oasis:names:tc:ebxml-regrep:ErrorSeverityType:Error"></RegistryError>
      </RegistryErrorList>
    </RegistryResponse>
  </ContentStream>
  <AdditionalInfo>
    <AdditionalInfoItem AdditionalInfoKey="ResponseSOAPAction">urn:ihe:iti:2007:ProvideAndRegisterDocumentSet-bResponse</AdditionalInfoItem>
  </AdditionalInfo>
</XMLMessage>

I want to extract RegistryResponse/RegistryErrorList/RegistryError/@errorCode from this message. 

do ##class(%XML.XPATH.Document).CreateFromStream(pResponse.ContentStream, .tPnRXML) //pResponse seen above
// EITHER
$$$THROWONERROR(tSC,tPnRXML.EvaluateExpression("node-test","node-value",.tPnRResult)))
// OR
$$$THROWONERROR(tSC,##class(HS.IHE.Util).GetXPathValue(pResponse.ContentStream,"node-test","node-value",.tPnRResult,.tPnRXML))

I have tried way too many permutations of the XPath query to list. I have used them in both methods and got no results by this point.

 

If anyone was able to simulate the problem on their system and find a solution, I'd be grateful. It's either entirely obvious or a WRC post. I'm sorry in advance for any comment responses that are just "Already tried this, didn't work." That is the nature of the beast, as they say.

 

Thank you,

Jakub Hemala

Product version: IRIS 2021.1
$ZV: IRIS for Windows (x86-64) 2021.1 (Build 215_0_21260U) Tue Nov 9 2021 19:30:33 EST
Discussion (4)2
Log in or sign up to continue

Output on my machine:

HSROUTER>w tPnRXML.EvaluateExpression("/XMLMessage/ContentStream/RegistryResponse/RegistryErrorList/RegistryError","@errorCode",.tPnRResult)
1
HSROUTER>set tErrorCode = tPnRResult.GetAt(1).Value                              
SET tErrorCode = tPnRResult.GetAt(1).Value
^
<INVALID OREF>
HSROUTER>w tPnRResult.Size                                                      
0

(tPnRXML was set higher)

I believe this is due to the XML Document being created from the ContentStream part of the Response body. However the simple solution of just removing the first (two) steps of the XPath doesn't help either.

HSROUTER>w tPnRXML.EvaluateExpression("/ContentStream/RegistryResponse/RegistryErrorList/RegistryError","@errorCode",.tPnRResult)
1
HSROUTER>w tPnRResult.Size                                                      
0
HSROUTER>w tPnRXML.EvaluateExpression("/RegistryResponse/RegistryErrorList/RegistryError","@errorCode",.tPnRResult)
1
HSROUTER>w tPnRResult.Size                                                      
0

This reveals the main reason I had to come ask for help here.

Sorry, forgot the namespace, try this:

do ##class(%XML.XPATH.Document).CreateFromStream(pResponse.ContentStream, .tPnRXML)
Set tPnRXML.PrefixMappings="ns urn:oasis:names:tc:ebxml-regrep:xsd:rs:3.0"
Set sc=tPnRXML.EvaluateExpression("/XMLMessage/ContentStream/ns:RegistryResponse/ns:RegistryErrorList/ns:RegistryError","@errorCode",.tPnRResult)
Set tPnRResult.GetAt(1).Value ; Value=XDSRegistryDeprecatedDocumentError

Okay, with a bit of fiddling, that did the trick. I have attempted to set PrefixMappings in my previous solutions but it appears I did it wrong then.

Output:

HSROUTER>Set tPnRXML.PrefixMappings="ns urn:oasis:names:tc:ebxml-regrep:xsd:rs:3.0"
HSROUTER>w tPnRXML.EvaluateExpression("/XMLMessage/ContentStream/ns:RegistryResponse/ns:RegistryErrorList/ns:RegistryError","@errorCode",.tPnRResult)
1
HSROUTER>w tPnRResult.Size                                                      
0
HSROUTER>w tPnRXML.EvaluateExpression("/ContentStream/ns:RegistryResponse/ns:RegistryErrorList/ns:RegistryError","@errorCode",.tPnRResult)
1
HSROUTER>w tPnRResult.Size                                                      
0
HSROUTER>w tPnRXML.EvaluateExpression("/ns:RegistryResponse/ns:RegistryErrorList/ns:RegistryError","@errorCode",.tPnRResult)
1
HSROUTER>w tPnRResult.Size                                                     
1
HSROUTER>w tPnRResult.GetAt(1).Value                                           
XDSRegistryDeprecatedDocumentError

Thank you very much.