无法在 Yii2 中将肥皂响应字符串转换为 xml
我有一个肥皂请求.我能够发送请求并获得字符串响应.现在我想将其转换为 XML 并从中获取所需的数据.
I have a soap request. I am able to send the request and get a response in a string. Now I want to convert it into XML and get the required data from it.
回复
string(1383) "
<?xml version="1.0" encoding="UTF-8"?>
<ResponseMessage xmlns:ns="http://iec.ch/TC57/2011/schema/message" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://iec.ch/TC57/2011/schema/message Message.xsd">
<Header>
<Verb>reply</Verb>
<Noun>EndDeviceControls</Noun>
<Revision>2.0</Revision>
<Timestamp>2019-05-04T10:39:11+04:30</Timestamp>
<Source>HES-BSTC</Source>
<AsyncReplyFlag>true</AsyncReplyFlag>
<ReplyAddress>http://ip:port/AmiWeb/services/Metering</ReplyAddress>
<User>
<UserID>user</UserID>
</User>
<MessageID>6C3F761B-A1EC-4EBE-BB49-67B720C5AE62</MessageID>
<CorrelationID>1001</CorrelationID>
<Property>
<Name>password</Name>
<Value>password</Value>
</Property>
<Property>
<Name>timeout(m)</Name>
<Value>30</Value>
</Property>
</Header>
<Reply>
<Result>OK</Result>
<Error>
<code>0.3</code>
</Error>
</Reply>
</ResponseMessage>"
代码
$xml_post_string = /** @lang text */
'<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soap="http://soap.inf.hexing.cn">
<soapenv:Header/>
<soapenv:Body>
<soap:doCommand>
<!--Optional:-->
<arg0><![CDATA[<?xml version="1.0" encoding="utf-8"?>
<RequestMessage
xmlns="http://iec.ch/TC57/2011/schema/message"
xmlns:m="http://iec.ch/TC57/2011/EndDeviceControls#"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://iec.ch/TC57/2011/schema/message Message.xsd">
<Header>
<Verb>create</Verb>
<Noun>EndDeviceControls</Noun>
<Revision>2.0</Revision>
<Timestamp>2016-01-01T00:00:00+04:30</Timestamp>
<Source>MDM</Source>
<AsyncReplyFlag>true</AsyncReplyFlag>
<ReplyAddress>http://ip:port/AmiWeb/services/Metering</ReplyAddress>
<AckRequired>true</AckRequired>
<User>
<UserID>'.$userName.'</UserID>
</User>
<MessageID>83c643e6-85c5-43c0-9e0a-fa1deb469b72</MessageID>
<CorrelationID>1001</CorrelationID>
<Property>
<Name>password</Name>
<Value>'.$password.'</Value>
</Property>
<Property>
<Name>timeout(m)</Name>
<Value>30</Value>
</Property>
</Header>
<Payload>
<m:EndDeviceControls>
<m:EndDeviceControl>
<m:reason>Disconnect/Reconnect</m:reason>
<m:EndDeviceControlType ref="3.0.211.23"/>
<m:EndDevices>
<m:mRID>'.$msn.'</m:mRID>
<m:Names>
<m:name>Disconnect</m:name>
<m:NameType>
<m:name>ControlType</m:name>
</m:NameType>
</m:Names>
</m:EndDevices>
</m:EndDeviceControl>
</m:EndDeviceControls>
</Payload>
</RequestMessage>
]]></arg0>
</soap:doCommand>
</soapenv:Body>
</soapenv:Envelope>';
$headers = array(
"Content-type: text/xml;charset="utf-8"",
"Accept: text/xml",
"Cache-Control: no-cache",
"Pragma: no-cache",
//"SOAPAction: http://connecting.website.com/WSDL_Service/GetPrice",
"Content-length: ".strlen($xml_post_string),
); //SOAPAction: your op URL
$url = $soapUrl;
// PHP cURL for https connection
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post_string); // the SOAP request
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// converting
$response = curl_exec($ch);
curl_close($ch);
$xml = simplexml_load_string($response);
var_dump($xml);
die();
输出
object(SimpleXMLElement)#121 (0) { }
输出为空.现在我想要两件事
The output is empty. Now I want two things
- 将字符串转换为 XML
- 从返回的 XML 我想从响应中获取
true
的值
更新 1
根据建议,我添加了以下代码
As per suggestion, I have added below code
$xml = simplexml_load_string($response);
echo $xml->asXML();
输出
<?xml version="1.0" encoding="UTF-8"?>
<ResponseMessage xmlns:ns="http://iec.ch/TC57/2011/schema/message" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://iec.ch/TC57/2011/schema/message Message.xsd">
<Header>
<Verb>reply</Verb>
<Noun>EndDeviceControls</Noun>
<Revision>2.0</Revision>
<Timestamp>2019-05-04T14:01:48+04:30</Timestamp>
<Source>HES-BSTC</Source>
<AsyncReplyFlag>true</AsyncReplyFlag>
<ReplyAddress>http://ip:port/AmiWeb/services/Metering</ReplyAddress>
<User>
<UserID>user</UserID>
</User>
<MessageID>F4E15012-D009-4CBC-A610-E937F2620193</MessageID>
<CorrelationID>1001</CorrelationID>
<Property>
<Name>password</Name>
<Value>password</Value>
</Property>
<Property>
<Name>timeout(m)</Name>
<Value>30</Value>
</Property>
</Header>
<Reply>
<Result>OK</Result>
<Error>
<code>0.3</code>
</Error>
</Reply>
</ResponseMessage>
我尝试了什么?
$xml = new SimpleXMLElement($response);
print_r($xml);
die();
它给了我一个空的结果
$doc = new DOMDocument('1.0', 'utf-8');
$doc->loadXML($response);
$XMLresults = $doc->getElementsByTagName("AsyncReplyFlag")->item(0)->textContent;
echo $XMLresults;
die();
它给了我一个错误
试图获取非对象的属性$XMLresults = $doc->getElementsByTagName("AsyncReplyFlag")->item(0)->textContent;
Trying to get property of non-object $XMLresults = $doc->getElementsByTagName("AsyncReplyFlag")->item(0)->textContent;
仍然无法获取true
Still, I am unable to get the value of <AsyncReplyFlag>true</AsyncReplyFlag>
我怎样才能实现它?任何帮助将不胜感激.
How can I achieve it? Any help would be highly appreciated.
推荐答案
DOMDocument 提取它应该没有问题,作为一个快速的单行:
DOMDocument should have no problem extracting it, as a quick one-liner:
echo (@DOMDocument::loadXML($response))->getElementsByTagName("AsyncReplyFlag")->item(0)->textContent;
...或者如果您想在每一步都仔细检查错误,
... or if you want to meticulously check for errors every step of the way,
$xml_errors=[];
set_error_handler(function(int $errno, string $errstr, string $errfile, int $errline, array $errcontext) use(&$xml_errors){
ob_start();
call_user_func_array('var_dump',func_get_args());
$xml_errors[]=ob_get_clean();
});
$domd=new DOMDocument();
$loaded=$domd->loadXML($response);
restore_error_handler();
if(!$loaded){
if(defined('STDERR')){
fprintf(STDERR,"%s",$response);
}
throw new RuntimeException("errors parsing XML! xml printed in stderr, parsing errors: ".print_r($xml_errors,true));
}
$ele=$domd->getElementsByTagName("AsyncReplyFlag");
if($ele->length<1){
if(defined('STDERR')){
fprintf(STDERR,"%s",$response);
}
throw new RuntimeException("did not get AsyncReplyFlag in response! (xml printed in stderr)");
}
echo $ele->item(0)->textContent;
相关文章