Php 无法在Yi2中将soap响应字符串转换为xml

Php 无法在Yi2中将soap响应字符串转换为xml,php,xml,curl,soap,Php,Xml,Curl,Soap,我有一个soap请求。我能够发送请求并获得字符串形式的响应。现在我想将其转换为XML并从中获取所需的数据 响应 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:schema

我有一个soap请求。我能够发送请求并获得字符串形式的响应。现在我想将其转换为XML并从中获取所需的数据

响应

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();
代码

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();
输出为空。现在我想要两样东西

  • 将字符串转换为XML的步骤
  • 从返回的XML中,我想从响应中获得
    true
    的值
  • 更新1

    根据建议,我添加了以下代码

    $xml = simplexml_load_string($response);
                            echo $xml->asXML();
    
    输出

    object(SimpleXMLElement)#121 (0) { }
    
    <?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”)->项(0)->文本内容

    但是,我无法获得
    true

    我怎样才能做到呢?
    任何帮助都将不胜感激。

    尝试使用
    var\u dump()
    输出SimpleXMLElement都不是一个好主意,正如您所看到的,也不会给您带来太多帮助

    如果您只想查看它加载的XML,请使用

    echo $xml->asXML();
    
    这将向您显示XML已加载OK,因此您只需在

    $xml = simplexml_load_string($response);
    echo $xml->Header->AsyncReplyFlag;
    

    尝试使用
    var\u dump()
    输出SimpleXMLElement并不是一个好主意,正如您所看到的,也不会带来太多好处

    如果您只想查看它加载的XML,请使用

    echo $xml->asXML();
    
    这将向您显示XML已加载OK,因此您只需在

    $xml = simplexml_load_string($response);
    echo $xml->Header->AsyncReplyFlag;
    

    使用
    XPath
    查询

    $xml = new SimpleXMLElement($xmlData);
    echo $xml->xpath('//AsyncReplyFlag')[0];
    

    您可以使用
    xml\u解析器\u创建

    $p = xml_parser_create();
    xml_parse_into_struct($p, $xml, $values, $indexes);// $xml containing the XML
    xml_parser_free($p);
    
    echo $values[12]['value'];
    

    有关其他详细信息,您可以使用
    XPath
    查询
    print\r($values)

    $xml = new SimpleXMLElement($xmlData);
    echo $xml->xpath('//AsyncReplyFlag')[0];
    

    您可以使用
    xml\u解析器\u创建

    $p = xml_parser_create();
    xml_parse_into_struct($p, $xml, $values, $indexes);// $xml containing the XML
    xml_parser_free($p);
    
    echo $values[12]['value'];
    

    有关其他详细信息,您可以
    print\r($values)

    DOMDocument提取它应该没有问题,作为一个快速的单行程序:

    echo (@DOMDocument::loadXML($response))->getElementsByTagName("AsyncReplyFlag")->item(0)->textContent;
    
    。。。或者如果你想仔细检查每一步的错误

    $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;
    
    $xml_errors=[];
    set_error_处理程序(函数(int$errno、string$errstr、string$errfile、int$errline、array$errcontext)使用(&$xml_errors){
    ob_start();
    调用用户函数数组('var_dump',func_get_args());
    $xml_errors[]=ob_get_clean();
    });
    $domd=新的DOMDocument();
    $loaded=$domd->loadXML($response);
    还原错误处理程序();
    如果(!$loaded){
    如果(已定义('STDERR')){
    fprintf(标准字符,“%s”,$response);
    }
    抛出new\RuntimeException(“解析XML时出错!在stderr中打印的XML,解析错误:”.print\r($XML\u errors,true));
    }
    $ele=$domd->getElementsByTagName(“AsyncReplyFlag”);
    如果($ele->lengthitem(0)->textContent;
    
    DOMDocument提取它应该没有问题,因为它是一个快速的单行程序:

    echo (@DOMDocument::loadXML($response))->getElementsByTagName("AsyncReplyFlag")->item(0)->textContent;
    
    …或者如果你想仔细检查每一步的错误

    $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;
    
    $xml_errors=[];
    set_error_处理程序(函数(int$errno、string$errstr、string$errfile、int$errline、array$errcontext)使用(&$xml_errors){
    ob_start();
    调用用户函数数组('var_dump',func_get_args());
    $xml_errors[]=ob_get_clean();
    });
    $domd=新的DOMDocument();
    $loaded=$domd->loadXML($response);
    还原错误处理程序();
    如果(!$loaded){
    如果(已定义('STDERR')){
    fprintf(标准字符,“%s”,$response);
    }
    抛出new\RuntimeException(“解析XML时出错!在stderr中打印的XML,解析错误:”.print\r($XML\u errors,true));
    }
    $ele=$domd->getElementsByTagName(“AsyncReplyFlag”);
    如果($ele->lengthitem(0)->textContent;
    

    1:字符串已经是XML。2:
    $asyncReplyFlag=(@DOMDocument::loadHTML($response))->getElementsByTagName(“asyncReplyFlag”)->item(0)->textContent;
    @hanshenrik not working1:字符串已经是XML。2:
    $asyncReplyFlag=(@DOMDocument::loadHTML($response))->getElementsByTagName(“asyncReplyFlag”)->项(0)->textContent;
    @hanshenrik不工作
    echo$xml->Header->AsyncReplyFlag;
    它给了我一个空结果使用
    echo$xml->asXML();
    检查下一部分-试试
    echo$xml->Header->asXML()
    好的,看起来它的名称有问题,你能通过
    echo$xml->children()[0]->getName()检查这个问题吗?
    它给了我错误
    语法错误,意外的“echo”(T_echo)
    echo$xml->Header->AsyncReplyFlag;
    它给了我空结果使用
    echo$xml->asXML()检查xml有一些内容
    只是检查下一部分-尝试
    echo$xml->Header->asXML();
    好的,看起来它的名称有问题,你能通过
    echo$xml->children()[0]->getName()检查一下吗;
    它给我错误
    语法错误,意外的“echo”(T_echo)
    $response=curl_exec($ch);curl_close($ch);$xml=simplexml_load_string($response);$p=xml_parser_create();xml_parse_into_struct($p,$xml,$values,$index);/$xml包含xml_parser_free($p);print_r($values);die();
    它给了我
    Array()
    如果是正确的XML,您应该会得到结果XML响应是字符串
    string(1383)”
    您可以看到我的问题,我还添加了response@Faisal移除管柱(1383)从响应中,我在
    $response=curl\u exec($ch);curl\u close($ch);var\u dump($response);
    $response=curl\u exec($ch);curl\u close($ch);$xml=simplexml\u load\u string($response);$p=xml\u parser\u create();xml_parse_into_struct($p,$xml,$values,$index);/$xml包含xml_parser_free($p);print_r($values);die();
    它给了我