PHP Soap 没有创建正确的 xml 文档

PHP Soap doesn't create the correct xml document

我正在尝试使用此 WSDL 服务:https://wsaimport.uni-login.dk/wsaimport-v5/ws?WSDL

它需要一个 XML 文档,其中包含要导入的用户信息。导入人物时,有两个属性是必需的(根据https://wsaimport.uni-login.dk/wsaimport-v5/ws?xsd=1):(例如<xs:attribute name="protected" type="xs:boolean" use="required">)。

我生成一个包含所需信息(当然还有更多)的对象(用户和个人 ID 是假的):

object(XMLinst)#5 (1) { ["UNILoginImport"]=> object(UNILoginImport)#6 (5) { ["sourceDateTime"]=> string(19) "2018-10-20T00:15:54" ["source"]=> string(10) "SurveyInfo" ["schoolYear"]=> string(9) "2018-2019" ["sourceVersion"]=> string(3) "0.1" ["Institution"]=> object(Institution)#7 (4) { ["InstitutionNumber"]=> string(5) "10150" ["InstitutionName"]=> NULL ["Group"]=> object(Group)#8 (7) { ["GroupId"]=> string(2) "7b" ["GroupName"]=> string(3) "7.B" ["GroupType"]=> string(11) "Hovedgruppe" ["GroupLevel"]=> string(2) "DT" ["Line"]=> string(1) "B" ["FromDate"]=> string(10) "2018-08-01" ["ToDate"]=> string(10) "2019-06-30" } ["InstitutionPerson"]=> array(1) { [0]=> object(InstitutionPerson)#9 (5) { ["LocalPersonId"]=> string(11) "310900-8345" ["Person"]=> object(Person)#10 (16) { ["protected"]=> bool(false) ["verificationLevel"]=> string(1) "0" ["FirstName"]=> string(9) "Tester A." ["FamilyName"]=> string(9) "Testersen" ["CivilRegistrationNumber"]=> string(11) "310900-8345" ["EmailAddress"]=> NULL ["BirthDate"]=> string(10) "2000-09-31" ["Gender"]=> string(1) "M" ["PhotoId"]=> NULL ["AliasFirstName"]=> NULL ["AliasFamilyName"]=> NULL ["Address"]=> NULL ["HomePhoneNumber"]=> NULL ["WorkPhoneNumber"]=> NULL ["MobilePhoneNumber"]=> NULL ["GroupId"]=> string(2) "7b" } ["Student"]=> object(Student)#11 (6) { ["Role"]=> string(4) "Elev" ["StudentNumber"]=> NULL ["Level"]=> string(2) "DT" ["Location"]=> string(8) "B-rummet" ["MainGroupId"]=> string(2) "7b" ["GroupId"]=> NULL } ["Employee"]=> NULL ["Extern"]=> NULL } } } } }

我是调用客户端,然后是导入函数:

$unilogin = new SoapClient($WSDL,array("soap_version" => SOAP_1_2,'cafile' => "/etc/ssl/certs/surveyinfo.pem", 'cache_wsdl'=>"WSDL_CACHE_NONE", 'cache'=>"WSDL_CACHE_NONE", 'trace'=>true));

$unilogin->importerDeltaXml(array("wsBrugerid"=>$user,"wsPassword"=>$pass,"xml"=>$import));

这 return 是一个错误:

org.xml.sax.SAXParseException; cvc-complex-type.4: Attribute 'protected' must appear on element 'ns3:Person'.

来自 getLastResponse 的 return 看起来像这样:

<?xml version="1.0" encoding="UTF-8"?><env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="https://uni-login.dk" xmlns:ns2="https://uni-login.dk/data" xmlns:ns3="https://wsaimport.uni-login.dk/import" xmlns:ns4="https://wsaimport.uni-login.dk/ws"><env:Body><ns4:importerDeltaXml><ns1:wsBrugerid/><ns1:wsPassword/><ns4:xml><ns3:UNILoginImport sourceVersion="0.1" sourceDateTime="2018-10-20T00:12:28" source="SurveyInfo" schoolYear="2018-2019"><ns3:Institution><ns2:InstitutionNumber>10150</ns2:InstitutionNumber><ns2:Group><ns2:GroupId>7b</ns2:GroupId><ns2:GroupName>7.B</ns2:GroupName><ns2:GroupType>Hovedgruppe</ns2:GroupType><ns2:GroupLevel>DT</ns2:GroupLevel><ns2:Line>B</ns2:Line><ns2:FromDate>2018-08-01</ns2:FromDate><ns2:ToDate>2019-06-30</ns2:ToDate></ns2:Group><ns3:InstitutionPerson><ns2:LocalPersonId>310400-8444</ns2:LocalPersonId><ns3:Person><ns2:FirstName>Tester A.</ns2:FirstName><ns2:FamilyName>Testersen</ns2:FamilyName><ns2:CivilRegistrationNumber>310400-8444</ns2:CivilRegistrationNumber><ns2:BirthDate>2000-04-31</ns2:BirthDate><ns2:Gender>K</ns2:Gender></ns3:Person><ns3:Student><ns2:Role>Elev</ns2:Role><ns2:Level>DT</ns2:Level><ns2:Location>B-rummet</ns2:Location><ns2:MainGroupId>7b</ns2:MainGroupId></ns3:Student></ns3:InstitutionPerson></ns3:Institution></ns3:UNILoginImport></ns4:xml></ns4:importerDeltaXml></env:Body></env:Envelope>

如您所见,protectedverificationLevel 不是 XML 的一部分,即使它们存在于呈现给 SOAP 的对象中。正如您还看到的,PHP 中的 SOAP 客户端函数实际上能够按照 WSDL 文档的要求生成属性,因为它是在 <ns3:UNILoginImport> 标记中完成的。

我是不是遇到了 PHP 的 SoapClient 中的错误?还是 WSDL 文档有问题? (由丹麦政府机构制作,已有多家公司在使用)。

关于如何解决这个问题有什么建议吗?我尝试使用从 __getLastRequest 获得的 XML-文档,插入请求的属性,但是当发送此 XML-文档时,在通过新的 SoapVar 将其放入后,我得到 "Failed to copy a message"... 谢谢!

我通过以下方式扩展 SOAP 客户端找到了解决方法:

class HackSoapClient extends SoapClient {

        function __doRequest($request, $location, $action, $version, $one_way = NULL) {

            $request=str_replace('<ns3:Person>','<ns3:Person protected="false" verificationLevel="0">',$request);
            // parent call
            return parent::__doRequest($request, $location, $action, $version,$one_way);
        }
    }