2014-05-09 15 views
5

Bir API çağrım var. Arama XML'i geri döndürür, XML'e bir diziye dönüşür ve sonra jsonp çağrısında yanıtı geri göndermek için json_encode'u kullanırım. Yaptığım şey çalışıyor ancak API, bir duruma göre filtrelememe, başlangıç ​​ve bitiş zamanlarına göre filtreleme yapmamı ve odanın müsait olduğundan emin olmamı sağlıyor.Filtre Dizisi veya Başlangıç ​​ve Bitiş Zamanı arasındaki süreye sahip XML.

Birkaç jsponp çağrısı ile deliriyor. Yine, sahip olduğum şey çalışıyor ama sonuçlarla bir kez daha süzgeç etmenin bir yolunu bulmam gerekiyor. Doğru durumu ve doğru tarihi döndürdüm, ancak hala zamanları filtrelemem gerekiyor. Saat şu an 10:29 ise, saat 10: 30'a kadar rezerve edilmediğinden rezervasyon yaptırmak istemiyorum. Yani, şu anki saatim 10:29 ise, dizimdeki etkinliklerimi filtrelemem gerekiyor ve yalnızca şu anki zamanı olan başlangıç ​​ve bitiş zamanı olan etkinlikleri göstermem gerekiyor.

Dizimde 10-11 arası bir rezervasyon kalmalı, ancak dizimde 2-4 arası bir rezervasyon gösterilmemelidir. Dizinin ilk önce döndüğü bir XML belgesinin, bir dizinin, ardından JSON'un dediğim gibi teknik olarak filtrelemek için her türlü işi kullanabilirim. PHP süzmek için PHP, PHP süzmek için dizisi. Javascript bile PHP dosyasının ajax çağrısı ile hazır olduğunu destekliyor.

Dizim JSON'a dönmeden ve dönüş yapmadan önce. Filtre ettiğim zamanlar TimeEventStart ve TimeEventEnd olmalıdır. Geçerli Javascript saatini veya PHP tarih fonksiyon zamanını kullanabilirim. Ya diziyi filtreleyebilir veya süzmek için XMLPath gibi bir şey kullanabilirim. En verimli olandan emin değil ve en iyi şekilde çalışır.

$axml = Array{ 
    "Bookings":{ 
     "Data":[ 
     { 
      "BookingDate":[ 
       "2014-05-09T00:00:00" 
      ], 
      "RoomDescription":[ 
       "Room06" 
      ], 
      "TimeEventStart":[ 
       "2014-05-09T14:00:00" 
      ], 
      "TimeEventEnd":[ 
       "2014-05-09T14:30:00" 
      ], 
      "EventName":[ 
       "Jake Long" 
      ], 
      "SetupTypeDescription":[ 
       "(none)" 
      ], 
      "ReservationID":[ 
       "137" 
      ], 
      "OpenTime":[ 
       "1900-01-01T00:00:00" 
      ], 
      "CloseTime":[ 
       "1900-01-01T00:00:00" 
      ], 
      "EventTypeDescription":[ 
       [ 

       ] 
      ], 
      "BookingID":[ 
       "709" 
      ], 
      "TimeBookingStart":[ 
       "2014-05-09T14:00:00" 
      ], 
      "TimeBookingEnd":[ 
       "2014-05-09T14:30:00" 
      ], 
      "GMTStartTime":[ 
       "2014-05-09T18:00:00" 
      ], 
      "GMTEndTime":[ 
       "2014-05-09T18:30:00" 
      ], 
      "TimeZone":[ 
       "ET" 
      ], 
      "RoomCode":[ 
       "R06" 
      ], 
      "Room":[ 
       "Room 6" 
      ], 
      "RoomID":[ 
       "34" 
      ], 
      "StatusID":[ 
       "3" 
      ], 
      "EventTypeID":[ 
       "0" 
      ], 
      "DateAdded":[ 
       "2014-05-09T13:47:29.087" 
      ], 
      "DateChanged":[ 
       "2014-05-09T13:47:29.087" 
      ], 
      "ChangedBy":[ 
       "Admin" 
      ] 
     }, 
     { 
      "BookingDate":[ 
       "2014-05-09T00:00:00" 
      ], 
      "RoomDescription":[ 
       "Room06" 
      ], 
      "TimeEventStart":[ 
       "2014-05-09T18:00:00" 
      ], 
      "TimeEventEnd":[ 
       "2014-05-09T20:00:00" 
      ], 
      "EventName":[ 
       "Rob Brown" 
      ], 
      "SetupTypeDescription":[ 
       "(none)" 
      ], 
      "ReservationID":[ 
       "142" 
      ], 
      "OpenTime":[ 
       "1900-01-01T00:00:00" 
      ], 
      "CloseTime":[ 
       "1900-01-01T00:00:00" 
      ], 
      "EventTypeDescription":[ 
       [ 

       ] 
      ], 
      "BookingID":[ 
       "714" 
      ], 
      "TimeBookingStart":[ 
       "2014-05-09T18:00:00" 
      ], 
      "TimeBookingEnd":[ 
       "2014-05-09T20:00:00" 
      ], 
      "GMTStartTime":[ 
       "2014-05-09T22:00:00" 
      ], 
      "GMTEndTime":[ 
       "2014-05-10T00:00:00" 
      ], 
      "TimeZone":[ 
       "ET" 
      ], 
      "RoomCode":[ 
       "R06" 
      ], 
      "Room":[ 
       "Room 6" 
      ], 
      "RoomID":[ 
       "34" 
      ], 
      "StatusID":[ 
       "3" 
      ], 
      "EventTypeID":[ 
       "0" 
      ], 
      "DateAdded":[ 
       "2014-05-09T14:58:55.71" 
      ], 
      "DateChanged":[ 
       "2014-05-09T14:58:55.71" 
      ], 
      "ChangedBy":[ 
       "Admin" 
      ] 
     }, 
     { 
      "BookingDate":[ 
       "2014-05-09T00:00:00" 
      ], 
      "StartBookingDate":[ 
       "2014-05-09T00:00:00" 
      ], 
      "RoomDescription":[ 
       "Room06" 
      ], 
      "TimeEventStart":[ 
       "2014-05-09T11:00:00" 
      ], 
      "TimeEventEnd":[ 
       "2014-05-09T12:00:00" 
      ], 
      "EventName":[ 
       "Jimmy James" 
      ], 
      "SetupTypeDescription":[ 
       "(none)" 
      ], 
      "ReservationID":[ 
       "141" 
      ], 
      "OpenTime":[ 
       "1900-01-01T00:00:00" 
      ], 
      "CloseTime":[ 
       "1900-01-01T00:00:00" 
      ], 
      "EventTypeDescription":[ 
       [ 

       ] 
      ], 
      "BookingID":[ 
       "713" 
      ], 
      "TimeBookingStart":[ 
       "2014-05-09T11:00:00" 
      ], 
      "TimeBookingEnd":[ 
       "2014-05-09T12:00:00" 
      ], 
      "GMTStartTime":[ 
       "2014-05-09T15:00:00" 
      ], 
      "GMTEndTime":[ 
       "2014-05-09T16:00:00" 
      ], 
      "TimeZone":[ 
       "ET" 
      ], 
      "RoomCode":[ 
       "R06" 
      ], 
      "Room":[ 
       "Room 6" 
      ], 
      "RoomID":[ 
       "34" 
      ], 
      "StatusID":[ 
       "1" 
      ], 
      "EventTypeID":[ 
       "0" 
      ], 
      "DateAdded":[ 
       "2014-05-09T14:58:15.17" 
      ], 
      "DateChanged":[ 
       "2014-05-09T14:58:15.17" 
      ], 
      "ChangedBy":[ 
       "Admin" 
      ] 
     } 
     ] 
    } 
} 
; 

Dizimde XML'deki bir SOAP çağrısından döndürülüyor. Geri XML alma ve Sonra yayınlanmıştır diziye koymak xmlToArray adlı bir işlev kullanıyorum

$sxml = simplexml_load_string($xml) 

kullanıyorum.

$axml = xmlToArray($sxml); 

Bir diziye ve daha sonra JSON'a dönüştürmeden önce XML budur.

<?xml version="1.0" encoding="utf-8"?><Bookings> 
    <Data> 
    <BookingDate>2014-05-13T00:00:00</BookingDate> 
    <StartBookingDate>2014-05-13T00:00:00</StartBookingDate> 
    <RoomDescription>Room 06</RoomDescription> 
    <TimeEventStart>2014-05-13T10:00:00</TimeEventStart> 
    <TimeEventEnd>2014-05-13T10:30:00</TimeEventEnd> 
    <EventName>Jake Long</EventName> 
    <ReservationID>159</ReservationID> 
    <ClosedAllDay>false</ClosedAllDay> 
    <OpenTime>1900-01-01T00:00:00</OpenTime> 
    <CloseTime>1900-01-01T00:00:00</CloseTime> 
    <BookingID>731</BookingID> 
    <TimeBookingStart>2014-05-13T10:00:00</TimeBookingStart> 
    <TimeBookingEnd>2014-05-13T10:30:00</TimeBookingEnd> 
    <GMTStartTime>2014-05-13T14:00:00</GMTStartTime> 
    <GMTEndTime>2014-05-13T14:30:00</GMTEndTime> 
    <RoomCode>R09</RoomCode> 
    <Room>Room 9</Room> 
    <RoomID>37</RoomID> 
    <StatusID>3</StatusID> 
    <DateAdded>2014-05-13T08:38:22.36</DateAdded> 
    <DateChanged>2014-05-13T08:38:22.36</DateChanged> 
    </Data> 
</Bookings> 
+0

Xpath'i, XML düğümlerini getirmek/filtrelemek için kullanabilirsiniz. – ThW

+0

Orijinal veri kaynağını (XML) verebilir misiniz? Bir diziye dönüştürmek, verilerin kaybedilmesi anlamına gelir. – ThW

+0

Dizinin iyi olduğuna inanıyorum. Birkaç ekstra, gerekli olmayan XML öğelerini çıkardım. Bunu benim için daha da zorlaştırmak, Doğu Zaman'ım ve projenin Pasifik olması gerekiyor. Sağlanan cevabın yolunda olduğuna inanıyorum, sadece zamanı düzeltmem gerekiyor. – donlaur

cevap

4

Tamam, bu yüzden neyi istediğinizi filtrelemek için bazı PHP işlevleri yazdım.

Php'deki tarihleri ​​karşılaştırmak için bunları Unix zamanına dönüştürmek en kolay yoldur. İlk fonksiyon böyle yapar. Unix time, 1 Ocak 1970'den bu yana geçen süredir. Bunları dönüştürmek, iki kez karşılaştırmak için < ve> operatörlerini kullanabileceğiniz avantaj sağlar.

Bir sonraki işlev (şimdiDeğişim), geçerli sürenin iki kez arasında ($ başlangıç ​​ve $ end) arasında olup olmadığına bakar.

Daha sonra JSON dizginizi aldım (bu yazıyı yazarken XML kaynağını gerçekten göremediğimizden) ve PHP dizilerine dönüştürdüm. json_decode'daki ikinci parametre true olarak ayarlandığından, diziler olduğundan emin olabiliriz.

Son olarak, JSON içeriğinizin "veri" bölümündeki tüm rezervasyonlara giriyorum, GMTStart ve GMTEnd zamanlarını okuyarak işlevlerimizi kullanarak aralarında geçen sürenin olup olmadığını kontrol ediyorum. Öyle değilse, rezervasyonu $ bookings dizisinden kaldırırım.

Sonuç, yalnızca doğru süreleri olan rezervasyonlardır. Çıktım şimdi boştu, ama rezervasyonlarınız 2014-05-09 tarihleri ​​arasında ... Çünkü çalıştığı zamanı uyarladım.

Umarım bu cevap sizin ihtiyaçlarınıza uygundur.

function convertDateTime($datetime) { 
    //FORMAT IS date("YYYY-MM-DDThh:mm:ss") 
    $datetime = str_replace("T"," ",$datetime); 
    return date("U",strtotime($datetime)); 
} 
function nowBetween($start,$end) { 
    $now = gmdate("U"); 
    $start = convertDateTime($start); 
    $end = convertDateTime($end); 
    if ($start <= $now && $end > $now) 
    { 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 

$bookings = '{"Bookings":{"Data":[{"BookingDate":["2014-05-09T00:00:00"],"RoomDescription":["Room06"],"TimeEventStart":["2014-05-09T14:00:00"],"TimeEventEnd":["2014-05-09T14:30:00"],"EventName":["Jake Long"],"SetupTypeDescription":["(none)"],"ReservationID":["137"],"OpenTime":["1900-01-01T00:00:00"],"CloseTime":["1900-01-01T00:00:00"],"EventTypeDescription":[[]],"BookingID":["709"],"TimeBookingStart":["2014-05-09T14:00:00"],"TimeBookingEnd":["2014-05-09T14:30:00"],"GMTStartTime":["2014-05-09T18:00:00"],"GMTEndTime":["2014-05-09T18:30:00"],"TimeZone":["ET"],"RoomCode":["R06"],"Room":["Room 6"],"RoomID":["34"],"StatusID":["3"],"EventTypeID":["0"],"DateAdded":["2014-05-09T13:47:29.087"],"DateChanged":["2014-05-09T13:47:29.087"],"ChangedBy":["Admin"]},{"BookingDate":["2014-05-09T00:00:00"],"RoomDescription":["Room06"],"TimeEventStart":["2014-05-09T18:00:00"],"TimeEventEnd":["2014-05-09T20:00:00"],"EventName":["Rob Brown"],"SetupTypeDescription":["(none)"],"ReservationID":["142"],"OpenTime":["1900-01-01T00:00:00"],"CloseTime":["1900-01-01T00:00:00"],"EventTypeDescription":[[]],"BookingID":["714"],"TimeBookingStart":["2014-05-09T18:00:00"],"TimeBookingEnd":["2014-05-09T20:00:00"],"GMTStartTime":["2014-05-09T22:00:00"],"GMTEndTime":["2014-05-10T00:00:00"],"TimeZone":["ET"],"RoomCode":["R06"],"Room":["Room 6"],"RoomID":["34"],"StatusID":["3"],"EventTypeID":["0"],"DateAdded":["2014-05-09T14:58:55.71"],"DateChanged":["2014-05-09T14:58:55.71"],"ChangedBy":["Admin"]},{"BookingDate":["2014-05-9T00:00:00"],"StartBookingDate":["2014-05-09T00:00:00"],"RoomDescription":["Room06"],"TimeEventStart":["2014-05-09T11:00:00"],"TimeEventEnd":["2014-05-09T12:00:00"],"EventName":["Jimmy James"],"SetupTypeDescription":["(none)"],"ReservationID":["141"],"OpenTime":["1900-01-01T00:00:00"],"CloseTime":["1900-01-01T00:00:00"],"EventTypeDescription":[[]],"BookingID":["713"],"TimeBookingStart":["2014-05-09T11:00:00"],"TimeBookingEnd":["2014-05-09T12:00:00"],"GMTStartTime":["2014-05-09T15:00:00"],"GMTEndTime":["2014-05-09T16:00:00"],"TimeZone":["ET"],"RoomCode":["R06"],"Room":["Room 6"],"RoomID":["34"],"StatusID":["1"],"EventTypeID":["0"],"DateAdded":["2014-05-09T14:58:15.17"],"DateChanged":["2014-05-09T14:58:15.17"],"ChangedBy":["Admin"]}]}}'; 
$bookings = json_decode($bookings,true); 


foreach ($bookings["Bookings"]["Data"] as $index=>$arrContent) 
{ 
    if (!nowBetween($arrContent["GMTStartTime"][0],$arrContent["GMTEndTime"][0])) 
    { 
     unset($bookings["Bookings"]["Data"][$index]); 
    } 
} 
+0

Yaptığınız kodu şununla değiştirerek kodunuzu kısaltabileceğinizi unutmayın: "return ($ start <= $ now && $ end> ​​$ now);" ama bu yolla çalışmanın – JohannesB

+0

daha net olduğunu düşündüm. Bunu göstermek için soruyu güncellediğim için dizim aslında $ axml'ye atandı. – donlaur

+1

Bunun benim için çalıştığını düşünüyorum. Diğer XML Xpath örneği de iyidir. – donlaur

6

Xpath'i kullanarak XML'e filtre uygulayabilirsiniz. Xpath 1.0 dizeleri karşılaştırılamaz, ancak php işlevlerini de kaydedebilirsiniz.

function isBetween($current, $min, $max) { 
    $current = strtotime($current.'Z'); 
    $min = strtotime($min.'Z'); 
    $max = strtotime($max.'Z'); 
    return $current >= $min && $current <= $max; 
} 

bir DOM belgesi oluşturun ve XML yüklemek:

Yani PHP'de koşulu yazın. Xpath örneğini PHP ad alanını ve işlevi kaydettirin.

$result = []; 
foreach($xpath->evaluate($expression) as $dataNode) { 
    $record = []; 
    // convert the matching data into a record array 
    foreach ($xpath->evaluate('*', $dataNode) as $childNode) { 
    $record[$childNode->localName] = $childNode->nodeValue; 
    } 
    $result[] = $record; 
} 
var_dump($result); 

Deneme: https://eval.in/151732

XPath ifade kullanarak Veri elemanı düğümleri Fetch

// use gmtime() for current time 
$now = strtotime('2014-05-13T14:00:00Z'); 
$expression = sprintf(
    '/Bookings/Data[ 
    php:function("isBetween", "%s", string(GMTStartTime), string(GMTEndTime)) 
    ]', 
    gmdate('Y-m-d\\TH:i:s', $now) 
); 

:

$dom = new DOMDocument(); 
$dom->loadXml($xml); 
$xpath = new DOMXpath($dom); 
$xpath->registerNamespace("php", "http://php.net/xpath"); 
$xpath->registerPhpFunctions('isBetween'); 

Veri elemanı düğümleri filtre işlevini kullanan bir XPath ifade tanımla

2

Anladığım kadarıyla’de birkaç kayıt alacaksınızRezervasyonları>? O zaman iki seçeneğiniz vardır: Eğer kayıtların sayısı her zaman çok büyükse - binlerce kişiden daha fazla ise, XPath'i bir diziye dönüştürmeden ÖNCE XPath -> sorgu sonucundan yeni belgeye kopyalayın ve bu belgeyi dönüştürün. sıralamak.

$filteredResult = array_filter($data, function($row) { 
    // parse dates and compare them.  
}); 

Ve filtrelenmiş diziyi alacak: Sadece buna benzer bir geri arama ile array_filter kullanmak - kayıtların sayısı küçükse sonra o zaman onları dönüştürmek daha kolaydır.

İlgili konular