Solved! I have some potential fixes for base_soap_formatter.pas with regards to the attributes and namespaces.
First I had to in my generated files change
//client = XRoadClientIdentifierType; ->
client = class(XRoadClientIdentifierType)
end;
...
typeRegistryInstance.Register(sNAME_SPACE,TypeInfo(client),'client');
to
get the headers registered in the proper namespace and name. Then I got
a bunch of different errors when the SOAP message was being formatted
and deserialized etc.
Here's how I solved these. First, in base_soap_formatter.pas in
function TSOAPBaseFormatter.InternalPutData
there's this section
if IsStrEmpty(s) then begin
namespaceShortName := 'ns' + IntToStr(NextNameSpaceCounter());
AddScopeAttribute('xmlns:'+namespaceShortName, namespaceLongName);
strNodeName := s + ':' + strNodeName;
end
I
figure that the last line is buggy, since we just created a short name
for namespace but we haven't set it to s. I simply replaced the last
line with
strNodeName := namespaceShortName + ':' + strNodeName;
Next,
I'm not sure why, maybe the formatter expects the response headers to
be in certain order or something but response deserializing was giving
errors on the objectType-attribute. I found out that in function
TSOAPBaseFormatter.GetNodeValue the following section was examining completely different header element than the attribute's node:
if ( FSerializationStyle = ssNodeSerialization ) then begin
locElt := StackTop().FindNode(strNodeName) As TDOMElement;
end else begin
locElt := GetCurrentScopeObject().GetAttributeNode(strNodeName);
end;
I figure GetCurrentScopeObject() gives the wrong element to examine since it was examining the second header in the response, which corresponded the position of my request's header elements. Somewhat hastily, I solved this by iterating through the siblings until no more siblings or I found the attribute, but I'm not sure if this is the best solution...
iterElt : TDOMNode;
...
end else begin
iterElt := GetCurrentScopeObject();
while ((locElt = nil) and (iterElt <> nil)) do begin
locElt := (iterElt as TDOMElement).getAttributeNode(strNodeName);
if locElt <> nil then break else iterElt := iterElt.nextSibling;
end;