从simplexml输出数据实时获取值并使用它来触发带有php

时间:2017-08-12 20:57:29

标签: php arrays xml

你好,伙计们,你好吗?我有这个项目,我已经做了很多次。这是一个警报和IP摄像头集成。到目前为止,我已经能够连接报警系统以接收XML输出,并且能够使用SimpleXML将其解析为具有以下代码的数组:

 <?php
//timeout limit
set_time_limit(0);

//Creating Socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
   // echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "<br />";
} else {
   // echo "OK.<br />";
}

//echo "Attempting to connect to the socket'...";
$result = socket_connect($socket, '192.168.43.50', 10001);
flush();
if ($result === false) {
   // echo "socket_connect() failed.<br />Reason: ($result) " . socket_strerror(socket_last_error($socket)) . "<br />";
} else {
  //  echo "OK.<br />";
}
$in = "GET / HTTP/1.1\r<br />";
$in .= "Host: 192.168.43.50\r<br />";
$in .= "Content-Type: application/xml; encoding=UTF-8\r\n";
$in .= "Accept: application/xml\n";
$in .= "Connection: Close\r<br />\r<br />";
$out= '';
while (socket_write($socket, $in, strlen($in))){

file_put_contents("intrusion.txt",socket_read($socket, 4096));
    $out = simplexml_load_string(file_get_contents("intrusion.txt",1,NULL,2))or die ("Error: Cannot create object");

    print_r ($out)."</br></br>";
    flush();
    ob_flush();

}
/*foreach ($v->PlatformIdentification->DeviceIdentification as $out) {
  $DeviceName = $out->DeviceName;
  $Detection = $out->DeviceName;
}*/
socket_close($socket);

/* Camera code 
function openCamFeed($zone)
{
    $camIP = array(
        'Z1'    =>  '192.168.43.50:10001', // :if port is needed
        'Z2'    =>  '192.168.43.51',
        'Z3'    =>  '192.168.43.52',
        'Z4'    =>  '192.168.43.53',
        'Z5'    =>  '192.168.43.54',
        'Z6'    =>  '192.168.43.55',
        'Z7'    =>  '192.168.43.56',
        'Z8'    =>  '192.168.43.57',
        'Z9'    =>  '192.168.43.58',
        'Z10'   =>  '192.168.43.59',
        'Z11'   =>  '192.168.43.60',
        'Z12'   =>  '192.168.43.61',
    );
//echo $zone.'<br /><br />';
    /*if ($zone != '')
    {
        header("Location: http://".$camIP[$zone]);
    }
}*/
?>

所以现在我在如何从输出条件中获取节点值时遇到困难,在Web浏览器中触发相机IP的值。这是simplexml输出:

  

SimpleXMLElement对象([PlatformIdentification] =&gt; SimpleXMLElement   对象([DeviceName] =&gt; Chevron Esc [DeviceCategory] ​​=&gt;传感器   [DeviceType] =&gt; SPIDR APU)[PlatformStatusReport] =&gt;数组([0] =&gt;   SimpleXMLElement对象([PlatformIdentification] =&gt; SimpleXMLElement   对象([DeviceName] =&gt; Chevron Esc.H1 [DeviceCategory] ​​=&gt;传感器   [DeviceType] =&gt; SPIDR Hyperzone)[状态] =&gt; SimpleXMLElement对象   ([DeviceState] =&gt;安全[CommunicationState] =&gt;确定[更新时间] =&gt;   2017-08-12T11:19:19.248)[DeviceStatusReport] =&gt;的SimpleXMLElement   对象([DeviceIdentification] =&gt; SimpleXMLElement对象(   [DeviceName] =&gt; Chevron Esc.H1.Z1 [DeviceCategory] ​​=&gt;传感器   [DeviceType] =&gt; SPIDR区域)[状态] =&gt; SimpleXMLElement对象(   [DeviceState] =&gt;安全[CommunicationState] =&gt;确定[UpdateTime] =&gt;   2017-08-12T11:19:19.248)))[1] =&gt; SimpleXMLElement对象(   [PlatformIdentification] =&gt; SimpleXMLElement对象([DeviceName] =&gt;   Chevron Esc.H2 [DeviceCategory] ​​=&gt;传感器[DeviceType] =&gt; SPIDR   Hyperzone)[状态] =&gt; SimpleXMLElement对象([DeviceState] =&gt;   安全[CommunicationState] =&gt;确定[UpdateTime] =&gt;   2017-08-12T11:19:19.248)[DeviceStatusReport] =&gt;的SimpleXMLElement   对象([DeviceIdentification] =&gt; SimpleXMLElement对象(   [DeviceName] =&gt; Chevron Esc.H2.Z2 [DeviceCategory] ​​=&gt;传感器   [DeviceType] =&gt; SPIDR区域)[状态] =&gt; SimpleXMLElement对象(   [DeviceState] =&gt;安全[CommunicationState] =&gt;确定[UpdateTime] =&gt;   2017-08-12T11:19:19.248)))))SimpleXMLElement对象(   [DeviceDetectionRecord] =&gt; SimpleXMLElement对象(   [DeviceIdentification] =&gt; SimpleXMLElement对象([DeviceName] =&gt;   Chevron Esc.H1.Z1 [DeviceCategory] ​​=&gt;传感器[DeviceType] =&gt; SPIDR   区域)[检测] =&gt; SimpleXMLElement对象([ID] =&gt; SZ003   [DetectionEvent] =&gt;入侵[UpdateTime] =&gt; 2017-08-12T11:19:34.650   )))SimpleXMLElement对象([DeviceDetectionRecord] =&gt;   SimpleXMLElement对象([DeviceIdentification] =&gt; SimpleXMLElement   对象([DeviceName] =&gt; Chevron Esc.H2.Z2 [DeviceCategory] ​​=&gt;传感器   [DeviceType] =&gt; SPIDR区域)[检测] =&gt; SimpleXMLElement对象(   [ID] =&gt; SZ004 [DetectionEvent] =&gt;入侵[UpdateTime] =&gt;   2017-08-12T11:19:34.650)))

这就是两个区域的simplexml输出。如果它增加了,我们将为其他区域创建更多阵列,我们在项目中有近12个区域,我将在xml文件中使用的信息是:

  

SimpleXMLElement对象([DeviceDetectionRecord] =&gt; SimpleXMLElement   对象([DeviceIdentification] =&gt; SimpleXMLElement对象(   [DeviceName] =&gt; Chevron Esc.H1.Z1 [DeviceCategory] ​​=&gt;传感器   [DeviceType] =&gt; SPIDR区域)[检测] =&gt; SimpleXMLElement对象(   [ID] =&gt; SZ003 [DetectionEvent] =&gt;入侵[UpdateTime] =&gt;   2017-08-12T11:19:34.650)))SimpleXMLElement对象(   [DeviceDetectionRecord] =&gt; SimpleXMLElement对象(   [DeviceIdentification] =&gt; SimpleXMLElement对象([DeviceName] =&gt;   Chevron Esc.H2.Z2 [DeviceCategory] ​​=&gt;传感器[DeviceType] =&gt; SPIDR   区域)[检测] =&gt; SimpleXMLElement对象([ID] =&gt; SZ004   [DetectionEvent] =&gt;入侵[UpdateTime] =&gt; 2017-08-12T11:19:34.650   )))

只有在xml输出中检测到具有相应设备名称的入侵消息时,摄像机才会触发。

感谢您的反馈。

下面是真正的xml输出

OKay Nigel谢谢你,下面是我要处理的xml数据:

当设备一切正常时,我有下面的xml;

<?xml version="1.0" encoding="UTF-8"?> <PlatformStatusReport> <PlatformIdentification> <DeviceName>ras</DeviceName> <DeviceCategory>Sensor</DeviceCategory> <DeviceType>SPIDR APU</DeviceType> </PlatformIdentification> <PlatformStatusReport> <PlatformIdentification> <DeviceName>ras.H1</DeviceName> <DeviceCategory>Sensor</DeviceCategory> <DeviceType>SPIDR Hyperzone</DeviceType> </PlatformIdentification> <Status> <DeviceState>Secure</DeviceState> <CommunicationState>OK</CommunicationState> <UpdateTime Zone="GMT">2017-08-13T19:32:45.157</UpdateTime> </Status> <DeviceStatusReport> <DeviceIdentification> <DeviceName>ras.H1.Z1</DeviceName> <DeviceCategory>Sensor</DeviceCategory> <DeviceType>SPIDR Zone</DeviceType> </DeviceIdentification> <Status> <DeviceState>Secure</DeviceState> <CommunicationState>OK</CommunicationState> <UpdateTime Zone="GMT">2017-08-13T19:32:45.157</UpdateTime> </Status> </DeviceStatusReport> </PlatformStatusReport> </PlatformStatusReport>

当有入侵时,我有下面的那个:我想要提取其信息的那个,比如DeviceName,DetectionEvent,它将成为触发相机监视该区域的条件

<?xml version="1.0" encoding="UTF-8"?> 
<DeviceDetectionReport>
 <DeviceDetectionRecord>
 <DeviceIdentification>
 <DeviceName>ras.H1.Z1</DeviceName>
<DeviceCategory>Sensor</DeviceCategory> 
<DeviceType>SPIDR Zone</DeviceType> 
</DeviceIdentification> 
<Detection> 
<ID>SZ001</ID> 
<DetectionEvent>Intrusion</DetectionEvent> 
<UpdateTime Zone="GMT">2017-08-13T19:32:44.864</UpdateTime> 
</Detection>
 </DeviceDetectionRecord> 
</DeviceDetectionReport>

已更新 新代码

<?php
error_reporting ( E_ALL );
ini_set ( 'display_errors', 1 );

//timeout limit
set_time_limit(0);

//Creating Socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
   // echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "<br />";
} else {
   // echo "OK.<br />";
}

//echo "Attempting to connect to the socket'...";
$result = socket_connect($socket, '192.168.43.50', 10001);
flush();
if ($result === false) {
   // echo "socket_connect() failed.<br />Reason: ($result) " . socket_strerror(socket_last_error($socket)) . "<br />";
} else {
  //  echo "OK.<br />";
}
$in = "GET / HTTP/1.1\r<br />";
$in .= "Host: 132.168.43.50\r<br />";
$in .= "Content-Type: application/xml; encoding=UTF-8\r\n";
$in .= "Accept: application/xml\n";
$in .= "Connection: Close\r<br />\r<br />";
$out= '';
while (socket_write($socket, $in, strlen($in))){

file_put_contents("intrusion.txt",socket_read($socket, 4096));
    $out = simplexml_load_string(file_get_contents("intrusion.txt",1,NULL,2))or die ("Error: Cannot create object");
    //print_r ($out)."</br></br>";
//$doc = new SimpleXMLElement ( $out );

if (isset ( $out->DeviceDetectionRecord )) {
    /*  $devname = "<strong>".$out->DeviceDetectionRecord->DeviceIdentification->
        DeviceName."</strong>" . PHP_EOL."</br></br>\n";
        //echo "Device:" . $devname;*/

    $identity= "<strong>". $out->DeviceDetectionRecord->Detection->
        ID ."</strong>". PHP_EOL."</br></br>";
        echo "ID:" .$identity;
    $detect = "<strong>".$out->DeviceDetectionRecord->Detection->
        DetectionEvent ."</strong>". PHP_EOL."</br></br>";
        echo "DetectionEvent:" . $detect;
    $date= "<strong>".$out->DeviceDetectionRecord->Detection->
        UpdateTime ."</strong>". PHP_EOL."</br></br>";
        echo "UpdateTime:" .$date;

        $deviceName = $out->DeviceDetectionRecord->DeviceIdentification->
DeviceName;
        $zone = explode('.', $deviceName)[2];

                /****** Camera code **********/
                            function openCamFeed($zone)
                            {
                                $camIP = array(
                                    'Z1'    =>  'https://www.youtube.com/watch?v=r7FxORx05Ns', // :if port is needed
                                    'Z2'    =>  'https://www.youtube.com/watch?v=00A4vjZ7dkY',
                                    'Z3'    =>  '192.168.43.52',
                                    'Z4'    =>  '192.168.43.53',
                                    'Z5'    =>  '192.168.43.54',
                                    'Z6'    =>  '192.168.43.55',
                                    'Z7'    =>  '192.168.43.56',
                                    'Z8'    =>  '192.168.43.57',
                                    'Z9'    =>  '192.168.43.58',
                                    'Z10'   =>  '192.168.43.59',                                   
                                    'Z11'   =>  '192.168.43.60',
                                    'Z12'   =>  '192.168.43.61',
                                );
                            //echo $zone.'<br /><br />';
                                if ($zone != '')
                                {
                                    header("Location: http://".$camIP[$zone]);
                                    echo "<video target='_blank' width='320' height='240' autoplay controls>";
                                            echo "<source src=".$camIP[$zone].  "type='video/mp4'>";
                                        echo    "<object width='320' height='240' type='application/x-shockwave-flash' data='http://releases.flowplayer.org/swf/flowplayer-3.2.5.swf'>";
                                            echo    "<param name='movie' value='http://releases.flowplayer.org/swf/flowplayer-3.2.5.swf' /> ";
                                                echo "<param name='flashvars' target='_blank value='config={'clip': {'url':".$camIP[$zone]."',' 'autoPlay':true, 'autoBuffering':true}} /> ";
                                            ///<p><a href='%StreamURL%">view with external app</a></p> 
                                        echo"   </object>";
echo "</video>";
                                //echo "<iframe align='middle' height='450px' width='900px' target='_blank' src=".$camIP[$zone]."></iframe>";
                                }
                            }


                openCamFeed($zone);

}
else {
    print_r ($out)."</br></br>\r\n";
    //echo "Nothing detected" . PHP_EOL;
} 

    flush();
    ob_flush();




}
/*foreach ($v->PlatformIdentification->DeviceIdentification as $out) {
  $DeviceName = $out->DeviceName;
  $Detection = $out->DeviceName;
}*/
socket_close($socket);


?>

新错误输出 警告:simplexml_load_string():实体:第21行:解析器错误:无法在第30行的C:\ xampp \ htdocs \ integration \ dataExtractor.php中找到Start Tag Devic第21行的结尾

警告:simplexml_load_string():

警告:第30行的C:\ xampp \ htdocs \ integration \ dataExtractor.php中的simplexml_load_string():^

警告:simplexml_load_string():实体:第21行:解析器错误:第30行的C:\ xampp \ htdocs \ integration \ dataExtractor.php中标记DeviceIdentification第20行中数据的过早结束

警告:simplexml_load_string():

警告:第30行的C:\ xampp \ htdocs \ integration \ dataExtractor.php中的simplexml_load_string():^

警告:simplexml_load_string():实体:第21行:解析器错误:第30行C:\ xampp \ htdocs \ integration \ dataExtractor.php中标记DeviceStatusReport第19行中数据的过早结束

警告:simplexml_load_string():

警告:第30行的C:\ xampp \ htdocs \ integration \ dataExtractor.php中的simplexml_load_string():^

警告:simplexml_load_string():实体:第21行:解析器错误:第30行C:\ xampp \ htdocs \ integration \ dataExtractor.php中标记PlatformStatusReport第8行中的数据提前结束

警告:simplexml_load_string():

警告:第30行的C:\ xampp \ htdocs \ integration \ dataExtractor.php中的simplexml_load_string():^

警告:simplexml_load_string():实体:第21行:解析器错误:第30行的C:\ xampp \ htdocs \ integration \ dataExtractor.php中标记PlatformStatusReport第2行中的数据提前结束

警告:simplexml_load_string():

警告:第30行的C:\ xampp \ htdocs \ integration \ dataExtractor.php中的simplexml_load_string():^ 错误:无法创建对象 结果 加载XML字符串失败未开始预期&#39;或&#34;格式错误的声明期望版本空白需要解析XML声明:&#39;?&gt;&#39;预期的开始标记,&#39;&lt;&#39;找不到加载XML字符串未开始预期&#39;或&#34;格式错误的声明期望版本空白需要解析XML声明:&#39;?&gt;&#39;预期的开始标记,&#39;&lt;&#39;找不到开始标记,&#39;&lt;&#39;找不到加载XML字符串未开始预期&#39;或&#34;格式错误的声明期望版本空白需要解析XML声明:&#39;?&gt;&#39;预期的开始标记,&#39;&lt;&#39;找不到开始标记,&#39;&lt;&#39;未找到无法找到开始标记更新时间行的结束17标记中数据的过早结束状态行14标记PlatformStatusReport行中数据的过早结束标记PlatformStatusReport行2中的数据过早结束加载XML字符串未启动期望& #39;或&#34;格式错误的声明期望版本空白需要解析XML声明:&#39;?&gt;&#39;预期的开始标记,&#39;&lt;&#39;找不到开始标记,&#39;&lt;&#39;未找到无法找到开始标记更新时间行17结束标记中数据的过早结束状态行14标记PlatformStatusReport行8中数据的过早结束标记PlatformStatusReport行2中的数据过早结束预期开始标记,&#39; &LT;&#39;找不到加载XML字符串未开始预期&#39;或&#34;格式错误的声明期望版本空白需要解析XML声明:&#39;?&gt;&#39;预期的开始标记,&#39;&lt;&#39;找不到开始标记,&#39;&lt;&#39;未找到无法找到开始标记更新时间行17结束标记中数据的过早结束状态行14标记PlatformStatusReport行8中数据的过早结束标记PlatformStatusReport行2中的数据过早结束预期开始标记,&#39; &LT;&#39;找不到开始标记,&#39;&lt;&#39;找不到

输出

ationState> <UpdateTime Zone="GMT">2017-09-17T16:24:58.547</UpdateTime> </Status> </DeviceStatusReport> </PlatformStatusReport> </PlatformStatusReport>

<?xml version="1.0" encoding="UTF-8"?> <PlatformStatusReport> <PlatformIdentification> <DeviceName>FD525R-103848</DeviceName> <DeviceCategory>Sensor</DeviceCategory> <DeviceType>SPIDR APU</DeviceType> </PlatformIdentification> <PlatformStatusReport> <PlatformIdentification> <DeviceName>FD525R-103848.HZONE-1</DeviceName> <DeviceCategory>Sensor</DeviceCategory> <DeviceType>SPIDR Hyperzone</DeviceType> </PlatformIdentification> <Stat
us> <DeviceState>Secure</DeviceState> <CommunicationState>OK</CommunicationState> <UpdateTime Zone="GMT">2017-09-17T16:25:18.532</UpdateTime> </Status> <DeviceStatusReport> <DeviceIdentification> <DeviceName>FD525R-103848.HZONE-1.ZONE-001</DeviceName> <DeviceCategory>Sensor</DeviceCategory> <DeviceType>SPIDR Zone</DeviceType> </DeviceIdentification> <Status> <DeviceState>Secure</DeviceState>
<CommunicationState>OK</CommunicationState> <UpdateTime Zone="GMT">2017-09-17T16:25:18.533</UpdateTime> </Status> </DeviceStatusReport> <DeviceStatusReport> <DeviceIdentification> <DeviceName>FD525R-103848.HZONE-1.ZONE-002</DeviceName> <DeviceCategory>Sensor</DeviceCategory> <DeviceType>SPIDR Zone</DeviceType> </DeviceIdentification> <Status> <DeviceState>Secure</DeviceState> <CommunicationState>O

APU生成的XML输出正在被截断 应将TCP连接视为流。单个TCP数据包不是消息。你可以在这里看到类似的问题: https://bytes.com/topic/net/answers/171941-parsing-xml-over-tcp-ip

那么您认为这里的问题是什么?

我们使用的解决方案是拥有一个读取TCP流并写入完整XML消息的对象。该对象通过跟踪XML结构来工作。当收到顶级XML实体的结束标记时,它将被视为完整的消息。

例如:

<DeviceIdentification>

  <DeviceName>CUSTOMNAME.HZONE-1.ZONE-2</DeviceName>

  <DeviceCategory>Sensor</DeviceCategory>

  <DeviceType>SPIDR Zone</DeviceType>

</DeviceIdentification>

<Detection>

  <ID>SZ002</ID>

  <DetectionEvent>Intrusion</DetectionEvent>

  <UpdateTime Zone="GMT">2017-10-08T15:12:34.000</UpdateTime>

</Detection>

第一行表示新消息正在开始,然后是顶级XML实体。收集流并将其组合为完整的消息,直到收到标记为止。

1 个答案:

答案 0 :(得分:0)

使用SimpleXML很容易,因为你的结构看起来很简单。我已经完成了一些代码,这些代码从检索到的XML开始(所以顶部的数据将由现有代码检索)。

这是检查XML事件的代码......

function checkForIntrusion ( string $xml )  {
    $doc = new SimpleXMLElement ( $xml );
    if (isset ( $doc->DeviceDetectionRecord )) {
        $detection = ["Device" => $doc->DeviceDetectionRecord
                                    ->DeviceIdentification
                                    ->DeviceName,
                "ID" => $doc->DeviceDetectionRecord->Detection->ID,
                "DetectionEvent" => $doc->DeviceDetectionRecord
                                    ->Detection->DetectionEvent,
                "UpdateTime" => $doc->DeviceDetectionRecord->Detection
                                    ->UpdateTime

        ];
    } else {
        $detection = false;;
    }

    return $detection;
}

以下使用的内容......

<?php
error_reporting ( E_ALL );
ini_set ( 'display_errors', 1 );

$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<DeviceDetectionReport>
    <DeviceDetectionRecord>
        <DeviceIdentification>
            <DeviceName>ras.H1.Z1</DeviceName>
            <DeviceCategory>Sensor</DeviceCategory>
            <DeviceType>SPIDR Zone</DeviceType>
        </DeviceIdentification>
        <Detection>
            <ID>SZ001</ID>
            <DetectionEvent>Intrusion</DetectionEvent>
            <UpdateTime Zone="GMT">2017-08-13T19:32:44.864</UpdateTime>
        </Detection>
    </DeviceDetectionRecord>
</DeviceDetectionReport>
XML;

$detection = checkForIntrusion($xml);
if ( $detection != false )  {
    echo "Device:" . $detection["Device"] . PHP_EOL;
    echo "ID:" . $detection["ID"] . PHP_EOL;
    echo "DetectionEvent:" . $detection["DetectionEvent"] . PHP_EOL;
    echo "UpdateTime:" . $detection["UpdateTime"] . PHP_EOL;

}

这会检查DeviceDetectionRecord并输出...

Device:ras.H1.Z1
ID:SZ001
DetectionEvent:Intrusion
UpdateTime:2017-08-13T19:32:44.864

此代码处理下一步操作 - 捕获视频或发送消息。

我不确定你打算如何使用它,但它也取决于你如何显示视频。如果您是通过网页运行此功能,则可以将该网页的一部分设置为来自摄像头的视频流。

更新

区域映射...... 底部的函数(已注释掉 - 因此将此函数放回并删除我之前添加的代码)openCamFeed应该能够执行您需要的操作,您只需要从deviceName中提取区域。你可以通过......来做到这一点。

$zone = explode('.', $deviceName)[2];
openCamFeed($zone);

由于您无法使用header()跳转到其他网页,因此您可以使用iframe代替......

<iframe src ="http://$camIP[$zone]/default.asp" width="100%" height="300">
    <p>Your browser does not support iframes.</p>
</iframe>

(这是来自https://www.cctvcamerapros.com/Embedding-IP-Camera-Web-Page-s/326.htm,所以我不确定它是否兼容,但值得一试)。如果这不起作用,您可以在没有/default.asp的情况下尝试。