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>
如您所见,protected
和 verificationLevel
不是 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);
}
}
我正在尝试使用此 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>
如您所见,protected
和 verificationLevel
不是 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);
}
}