Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wykrywanie zdublowanych rekordów w pliku xml
Forum PHP.pl > Forum > PHP
pepro
Witajcie.
Mój szef zadał mi pracę domową. Jest plik dane.xml o strukturze
  1. <dane>
  2. <rec>
  3. <name>nazwa</name>
  4. <address>adres</address>
  5. <city>miasto</city>
  6. <tel>600700800</tel>
  7. </rec>
  8. </dane>

Tych wpisów jest około 12000. wiele pól 'tel' się powtarza więc w jakiś magiczny sposób chciałbym wykryć zdublowane wpisy.
W efekcie chciałbym aby wylistowany był tylko jeden a nie kilka czy kilkanaście. Potem wygenerować zmodyfikowany plik dane.xml. Niby wszystko wiem tylko problemem pozostaje wyfiltrowanie i pozbycie się zdublowanych telefonów.

Mógłby mnie ktoś naprowadzić czego szukać lub podać jakiś przykład bym mógł sobie jakoś dojść do tego?

Serdeczne dzięki z góry za podpowiedzi.
adbacz
12000 wpisów w XML to troche dużo wg mnie.

Ale jeśli nie brać pod uwagę tego ile ich jest, to wystarczy parsowanie to obiektu lub tablicy, co Ci bardziej pasuje. Później dwie pętle i tyle:

  1. // Przechowujemy przefiltrowane dane
  2. $newData = array();
  3.  
  4. // Przechowuje oryginalną tablicę z elementami XML
  5. $currentData = array();
  6.  
  7. for($i=0, $count=count($currentData); $i<$count; $i++)
  8. {
  9. $isset = false;
  10.  
  11. for($j=0, $countj=count($newData); $j<$countj; $j++)
  12. {
  13. if($currentData[$i]['tel'] == $newData[$j]['tel'])
  14. {
  15. $isset = true;
  16. break;
  17. }
  18. }
  19.  
  20. if($isset === false)
  21. {
  22. $newData[] = $currentData[$i];
  23. }
  24. }


Takie coś powinno załatwić sprawę, ale nie wiem jak będzie z wydajnością. Jeśli to ma być tylko jednorazowe filtrowanie to ok, ale jeśli to ma działać częściej to warto pomyśleć nad innym wyjściem.
Crozin
@adbacz: 12.000 wpisów nie jest jakąś szczególnie wielką ilością, bez problemu można nad tym pracować.

1. Potrzebna będzie pomocnicza tablica, gdzie kluczami będą numery telefonów, zaś wartościami (do wyboru):
1.a. Ilość wystąpień (1, 2, 3...).
1.b. Kolejna tablica, zawierająca całą strukturę REC.
2. Potrzebna będzie druga pomocnicza tablica, w której przechowywać będziemy referencje do zdublowanych wpisów z pierwszej tablicy.
3. W przypadku, gdy do danego klucza pierwszej tablicy dopisujemy drugi rekord (wartość równa 2 w przypadku 1.a, bądź ilość elementów w tablicy równa 2 w przypadku 1.b ) tworzymy w drugiej pomocniczej tablicy referencję do owego klucza.

Po wykonaniu się skryptu, w pierwszej tablicy będziesz posiadał zgrupowane elementy (względem numeru telefonu), zaś w drugiej tablicy referencję do tych elementów, które reprezentują duplikat (2 lub więcej rekordów o tym samym numerze tel.)

EDIT: W drugiej tablicy zamiast referencji wystarczy trzymać klucz (tj. nr tel.).
irmidjusz
Zaskocz szefa, zrób to za pomocą XPath tongue.gif

W XPath 2 można banalnie prosto pobrać tylko unikatowe nody używając distinct-values().
w XPath 1 trzeba użyć transformacji XSLT, ale też się da.

Jest dużo przykładów w necie, szukaj w ulubionej wyszukiwarce frazy: select distinct values from xml using xpath
pepro
Hej.
Chętnie bym go zaskoczył, ale nie bardzo rozumiem co i jak. Usiłowałem znaleźć jakieś działający przykład by skumać co jest grane na jego przykładzie, ale jakoś mi nie wyszło.
Masz może, coś gotowego najlepiej z opisami bym doszedł o co chodzi? To pierwsza moja styczność z xml-em. Wcześniej tylko kontakt z xml-em miałem jak wysyłałem mape witryny do narzędzi google wink.gif

Treaz mam tak:
  1. <table>
  2. <?php
  3. echo 'Spis klientów: <br/>';
  4. $klienci = simplexml_load_file('/tmp/test2.xml');
  5. foreach($klienci -> record as $klient){
  6. echo'<tr>
  7. <td>Nazwa klienta: '.$klient -> nazwa.'</td>
  8. <td>Adres: '.$klient -> adres.'</td>
  9. <td>miasto: '.$klient -> city.'</td>
  10. <td>email: '.$klient -> email.'</td>
  11. </tr>';
  12. }
  13. ?>
  14. </table>

to mi ładnie listuje wszystko.

Podpowiedziane rozwiązanie przez "adbacz" myślę, że mi wystarczy. To ma raz na jakiś czas przefiltrować plik, więc powinno być ok, ale także nie bardzo wiem jak to kopnąć dalej.

adbacz
No to co teraz jest trudnego? Masz pętlę, zamień sobie te elementy, które wyświetlają wartości na przypisanie do zmiennej z pseudokodu, czyli do $currentData, a później zapodaj mój skrypt. Na wyjściu będziesz miał unialne rekordy, w których nie będzie się pojawiał numer telefonu więcej niż jeden raz.

To już jest zwykła praca z danymi, nic więcej opisu nie potrzebujesz, masz wszystko co potrzeba, teraz trzeba to skleić w całość. Masz i tak już nadto zadanie ułatwione bo masz nawet skrypt w zasięgu ręki, wystarczy skopiować i podstawić dane.
pepro
adbacz,
serdeczne dzięki za chęć pomocy, lecz za nic w świece nie mogę zrozumieć w jaki sposób to działa i w jaki sposób skleić to w jedną całość.
Ja odpuszczam, ale jakby pojawiło się rozwianie w postaci działającego przykładu to i ja i ludzie na moim poziomie w przyszłości mogliby z tego skorzystać.
Raz jeszcze dziękuję.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.