Problemen met het uitlezen van de RSS-feed via SimpleXML

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Java Developer / Overheid / Complexiteit

Functieomschrijving Wil jij als Java Developer een bijdrage leveren aan een veiliger Nederland en je als Java Developer bezig houden met zeer complexe bedrijfskritische applicaties? Lees dan snel verder! Doorontwikkelen bedrijfskritische applicaties; Aanpassingen maken in de bestaande applicatie; Vertalen van jouw visie op continuous integration en continuous delivery; Debuggen van de applicatie; In gesprek gaan met eindgebruikers om verbetervoorstellen op te halen. Functie-eisen Minimaal HBO-werk en denkniveau; Minimaal 5 jaar werkervaring als Java Developer; Je bent minimaal OCP-Java SE 6 gercertificeerd; Je hebt kennis van Webservices en Continuous Integration; Je bent analytisch sterk en zowel klant- als resultaatgericht. Bedrijfsomschrijving Binnen

Bekijk vacature »

Senior DevOps-ontwikkelaar eIDAS

Functie­omschrijving Burgers en bedrijven veilig en betrouwbaar digitaal toegang geven tot diensten en producten van het ministerie van Economische Zaken en Klimaat. Als senior DevOps-ontwikkelaar bouw je daar letterlijk aan mee. En dat doe je bij DICTU: een van de grootste en meest vooruitstrevende ICT-dienstverleners van de Rijksoverheid. Jij werkt mee aan de doorontwikkeling van eIDAS, dat staat voor Electronic IDentification Authentication and trust Services. Deze koppeling maakt de grensoverschrijdende authenticatie op overheidswebsites binnen de Europese Unie mogelijk. Het ministerie van Economische Zaken en Klimaat heeft één moderne toegangspoort voor zijn diensten en inspecties. Enkele daarvan zijn dankzij eIDAS inmiddels

Bekijk vacature »

Front-end Developer Vue.js Meewerkend voorman

Functieomschrijving Ben jij een ervaren Front-end Developer, bedreven in Vue.js en lijkt het jou gaaf om als meewerkend voorman verantwoordelijk te zijn voor de ontwikkeling van drie junior ontwikkelaars? Werk jij graag aan diverse projecten t.b.v. het vergroten van klant- en medewerkerbeleving? Lee dan snel verder! Het onderhouden, ontwikkelen en testen van front-end software van diverse klant- en medewerkersapplicaties; Het ontwikkelen van maatwerk front-end oplossingen in Vue.js en participeren in een scrumteam; Verantwoordelijk voor het begeleiden en coachen van drie junior front-end developers; Verantwoordelijk voor code-reviews en het opstellen van de juiste documentatie zoals userstories en api ontwerp; Participeren in

Bekijk vacature »

Tim Klein

Tim Klein

11/02/2020 18:33:14
Quote Anchor link
Hoi,

Ik ben bezig met het uitlezen van een Xml-feed, waarna ik deze wegschrijf in een SQL-database. Daarvoor gebruik ik de volgende code:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php
$affectedRow
= 0;

$xml = simplexml_load_file('https://alarmeringen.nl/feeds/user/76663/457abd70094d50a7d1dfde038f9e295c/timg.rss') or die("Error: Cannot create object");

foreach ($xml->channel->item as $row) {
    $Last_build = $row->lastBuildDate;
    
    //Select data from XML
    $title = $row->title;
    $pubDate = $row->pubDate;
    
    //Format the last date
    $unixtime = strtotime($pubDate);
    $Published_date = date("Y-m-d H:i:s",$unixtime);
    
    //Check if published date is the latest.
    $Check_last_date = mysqli_num_rows(mysqli_query($conn, "SELECT ID FROM Deployment_registration_alarms WHERE Published_date = '$Published_date'"));
    
    if($Check_last_date == '0'){    
        $sql = "INSERT INTO Deployment_registration_alarms(Alarm,Published_date) VALUES ('" . $title . "','" . $Published_date . "')";
    }

    
    $result = mysqli_query($conn, $sql);
    
    if (! empty($result)) {
        $affectedRow ++;
    }
else {
        $error_message = mysqli_error($conn) . "\n";
    }
    
}

?>


<?php
if ($affectedRow > 0) {
    //$message = $affectedRow . " records inserted";
} else {
    //$message = "No records inserted";
}

?>


Nu heb ik alleen één probleem: enkel de eerste regel wordt 25 keer in de database weggeschreven als deze er niet in staat. Ik had het werkend toen ik de RSS-link als lokaal bestand had staan (met exact de inhoud van de RSS-feed ge copy-pasted), maar nu ik deze verander in een link, werkt alleen de bovenste regel 25 keer. Wat doe ik fout?

Tim

Tim
 
PHP hulp

PHP hulp

10/08/2020 04:56:17
 
- Ariën -
Beheerder

- Ariën -

11/02/2020 18:36:24
Quote Anchor link
Lijn 20, moet je niet die quotes weghalen? Het gaat immers om integers.
Ik zou toch aanraden om de query in een aparte variabele op te slaan. Zo kan je makkelijker debuggen, en makkelijker foutafhandeling toevoegen.
 
Tim Klein

Tim Klein

11/02/2020 19:15:26
Quote Anchor link
Hoi Ariën! Dank je wel voor je snelle reactie!

Ik heb - zoals je aangaf - inderdaad de quotes weggehaald op regel 20. Daarnaast heb ik SQL nu losgehaald. Mijn code ziet er nu zo uit:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
$xml
= simplexml_load_file('https://alarmeringen.nl/feeds/user/76663/457abd70094d50a7d1dfde038f9e295c/timg.rss') or die("Error: Cannot create object");

foreach ($xml->children() as $row1) {
    foreach($row1->item as $row){
        
        //Select data from XML
        $title = $row->title;
        $pubDate = $row->pubDate;
        
        //Format the last date
        $unixtime = strtotime($pubDate);
        $Published_date = date("Y-m-d H:i:s",$unixtime);
        
        //Check if published date is the latest.
        $Sql_check_las_date = "SELECT ID FROM Deployment_registration_alarms WHERE Published_date = '$Published_date'";
        $Check_last_date = mysqli_num_rows(mysqli_query($conn, $Sql_check_las_date));
        
        if($Check_last_date == 0){    
            $sql = "INSERT INTO Deployment_registration_alarms(Alarm,Published_date) VALUES ('" . $title . "','" . $Published_date . "')";
        }

        
        mysqli_query($conn, $sql);
        
    }
}

?>


Zoals ik al aangaf, denk ik dat het licht aan de foreach. Immers, ik krijg wel 25 keer een regel erin. In eerste instantie laadt ik alles dus goed in. Als ik alleen één regel weg haal uit de SQL-database (lees: er komt een nieuwe post bij in de XML-file), gaat hij alle regels daaronder af, en worden alle onderstaande regels afgelopen.

Bijvoorbeeld:

Ik verwijder één regel uit de databsase, welke in de XML-file 10 items eronder heeft. Vervolgend worden er 10 regels met dezelfde datum en tekst in de SQL-database gezet.

Doe ik dit met een SQL-regel welke in de XML nog 19 regels eronder heeft, krijg ik 19 keer dezelfde alarmering in de tabel ge-insert.

Hoor graag van jullie!
 
- Ariën -
Beheerder

- Ariën -

11/02/2020 19:21:53
Quote Anchor link
Een geneste foreach? Dat lijkt mij niet echt logisch?
Je moet enkel de childs uitlezen. En daarbij controleer je in jouw geval welke de laatste is, waarna je een INSERT-query uitvoert.

Ik denk dat je met enig debugwerk al best wel ver moet komen. Dus sla de query eens los op, en kijk eens of die wel goed werkt. En check ook eens: $Check_last_date.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

11/02/2020 19:29:45
Quote Anchor link
Vervang regel 18 van je openings-post eens voor het volgende:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?php
    //Check if published date is the latest.
    $result = mysqli_query($conn, "SELECT ID FROM Deployment_registration_alarms WHERE Published_date = '$Published_date'");
    
    if($result === false) {
        echo mysqli_error($conn);
        exit;
    }

    $Check_last_date = mysqli_num_rows($result);
?>


Want als je query foutmeldingen oplevert zal num_rows uiteraard altijd gelijk zijn aan 0.
Gewijzigd op 11/02/2020 19:31:00 door Frank Nietbelangrijk
 
Thomas van den Heuvel

Thomas van den Heuvel

11/02/2020 19:45:46
Quote Anchor link
Maar ook: zijn het wel unieke publish dates, of zijn ze alle hetzelfde?

Ik zou @Ariën zijn voorstel volgen en alles eens debuggen.

Daarbij: het uitlezen van een feed en het wegschrijven naar een database zijn twee aparte dingen.

Die je prima in afzondering kunt behandelen.

Jouw vraagstuk is van de vorm: ik verricht achtereenvolgens handeling A B C D .... X Y Z en uit Z komt niet het gewenste resultaat. Waar gaat het mis? Sja... ergens tussen A en Z :).

Als je dit nu eens opsplitst in aparte onderdelen: zorg dat de uitvoer van A geschikt is als invoer van B et cetera. Op die manier deel je je probleem op in stukken.

Dus, lees eerst de feed eens uit en kijk wat voor data dit oplevert. Zorg dat dit geschikt is om in een database in te voeren. En daarbij moet je waarschijnlijk op een of andere manier vaststellen wat al in je database aanwezig is. Hiervoor heb je dus een of ander (uniek) criterium nodig waarbij je onderscheid kunt maken tussen reeds aanwezige en nieuwe items. Ook deze stap kun je in afzondering onderzoeken. En vervolgens (laatste) insert je enkel de nieuwe items.

Verdeel en heers.
 
Tim Klein

Tim Klein

11/02/2020 19:50:30
Quote Anchor link
Hoi allemaal!

Ik was een beetje blind voor mijn eigen fouten, maar heb het inmiddels opgelost.

Mijn probleem: de $result stond buiten de check. Daardoor werd deze voor iedere regel uitgevoerd, terwijl de $sql toch nog onthouden wordt uit de vorige (immers: ik definieer hem niet ergens op leeg). Ik heb deze nu binnen de if geplaatst, en nu werkt het wel zoals ik wil. Final code:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
$xml
= simplexml_load_file('https://alarmeringen.nl/feeds/user/76663/457abd70094d50a7d1dfde038f9e295c/timg.rss') or die("Error: Cannot create object");

foreach ($xml->channel->item as $row) {
        $Last_build = $row->lastBuildDate;
        
        //Select data from XML
        $title = $row->title;
        $pubDate = $row->pubDate;
        
        //Format the last date
        $unixtime = strtotime($pubDate);
        $Published_date = date("Y-m-d H:i:s",$unixtime);
        
        //Check if published date is the latest.
        $result = mysqli_query($conn, "SELECT ID FROM Deployment_registration_alarms WHERE Published_date = '$Published_date'");
        
        if($result === false) {
            echo mysqli_error($conn);
            exit;
        }

        
        $Check_last_date = mysqli_num_rows($result);    
        if($Check_last_date == '0'){    
            $sql = "INSERT INTO Deployment_registration_alarms(Alarm,Published_date) VALUES ('" . $title . "','" . $Published_date . "')";
            $result = mysqli_query($conn, $sql);
        }
        
}

?>


- Ariën - op 11/02/2020 19:21:53:
Een geneste foreach? Dat lijkt mij niet echt logisch?
Je moet enkel de childs uitlezen. En daarbij controleer je in jouw geval welke de laatste is, waarna je een INSERT-query uitvoert.

@Ariën, dit lijkt inderdaad niet logisch nee. Toch kan ik met de $xml->channel->item - string deze niet werkend krijgen. Vandaag deze dubbele foreache'jes.

Allen bedankt voor de hulp!
 
Michael -

Michael -

11/02/2020 19:51:21
Quote Anchor link
Ik zou beter naamgeving voor stellen. Ik vind 't nogal onoverzichtelijk om last_date en las_date te gebruiken.
Daarnaast pubDate en Published_date zeggen niet gelijk dat dit verschillende formaten zijn.
En waarom eerst $row->pubDate kopieren naar pubDate dan naar unixtime dan een nieuw format?
Je kunt deze stappen allemaal overslaan, en zelfs direct aan de query voeren mits je deze verder niet meer nodig hebt.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
$Published_date
= (new \DateTime($row->pubDate))->format('Y-m-d H:i:s');

//of direct

$Sql_check_las_date = "SELECT ID FROM Deployment_registration_alarms WHERE Published_date = '" . (new \DateTime($row->pubDate))->format('Y-m-d H:i:s') . "'";
?>


Toevoeging op 11/02/2020 20:34:54:

En in plaats van de check door eerst een SELECT uit te voeren en dan een INSERT als Published_date niet bestaat, kun je ook het veld Published_date een "UNIQUE KEY" geven. Dan gebruik je "INSERT IGNORE". Mocht de Published_date dat al bestaan, slaat die deze ook over.
 
Thomas van den Heuvel

Thomas van den Heuvel

11/02/2020 21:32:25
Quote Anchor link
Of: op het moment dat je een record tegenkomt wat je al kent ben je toch klaar, aangenomen dat alles op volgorde staat en er geen items met terugwerkende kracht worden toegevoegd? Hier zou je dan eventueel een break in kunnen bouwen.

Ook zouden prepared statements hier meerwaarde kunnen hebben omdat het elke keer eenzelfde soort query betreft.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.