[php+rss] <content:encoded> parsen

Pagina: 1
Acties:

  • ilovetechno
  • Registratie: Oktober 2001
  • Laatst online: 24-11 02:36
omdat het vorige topic (\[php+rss] <content:encoded> parsen) is gesloten beschrijf ik het probleem wat duidelijker .

Ik heb een script om vanuit een RSS data naar mysql web te schrijven. Zoals hieronder te zien is kun je bijvoorbeeld vanaf <description> tm </description> alles parsen. Dit werkt gelukkig allemaal heel goed. Alleen in RSS2.0 zit een tag die ik maar niet geparsed krijg. :? Dit is <content:encoded>.

Ik zit al 3 avonden te proberen maar ik kom er echt niet uit 8)7 . Nu bestaan er kant en klare classes e.d. die dit kunnen maar ditr script voldoet.

Heeft iemand enig idee hoe ik dit kan doen? Of wie kan mij op weg helpen?

PHP:
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<?php 

$connection = mysql_connect("x", 
                            "x_x", 
                            "x"); 
mysql_select_db("x", $connection); 

$counter = 0; 
$type = 0; 
$tag = ""; 
$itemInfo = array(); 
$channelInfo = array(); 
function unhtmlspecialchars( $string ) 
    { 
        $string = str_replace ( '&amp;', '&', $string ); 
        $string = str_replace ( ''', '\'', $string ); 
        $string = str_replace ( '&quot;', '\"', $string ); 
        $string = str_replace ( '&lt;', '<', $string ); 
        $string = str_replace ( '&gt;', '>', $string ); 
         
        return $string; 
    } 

function opening_element($xmlParser, $name, $attribute){ 


global $tag, $type; 

$tag = $name; 

if($name == "CHANNEL"){ 
$type = 1; 
} 
else if($name == "ITEM"){ 
$type = 2; 
} 

}//end opening element 

function closing_element($xmlParser, $name){ 

global $tag, $type, $counter; 

$tag = ""; 
if($name == "ITEM"){ 
$type = 0; 
$counter++; 
} 
else if($name == "CHANNEL"){ 
$type = 0; 
} 
}//end closing_element 

function c_data($xmlParser, $data){ 

global $tag, $type, $channelInfo, $itemInfo, $counter; 

$data = trim(htmlspecialchars($data)); 

if($tag == "TITLE" || $tag == "DESCRIPTION" || $tag == "THUMB" || $tag == "LINK"){ 
if($type == 1){ 

$channelInfo[strtolower($tag)] = $data; 

}//end checking channel 
else if($type == 2){ 

$itemInfo[$counter][strtolower($tag)] .= $data; 

}//end checking for item 
}//end checking tag 
}//end cdata funct 

$xmlParser = xml_parser_create(); 

xml_parser_set_option($xmlParser, XML_OPTION_CASE_FOLDING, TRUE); 
xml_parser_set_option($xmlParser, XML_OPTION_SKIP_WHITE, TRUE); 

xml_set_element_handler($xmlParser, "opening_element", "closing_element"); 
xml_set_character_data_handler($xmlParser, "c_data"); 

$fp = file($_GET['rss']); 

foreach($fp as $line){ 
if(!xml_parse($xmlParser, $line)){ 
die("Could not parse file."); 
} 
} 

foreach($itemInfo as $items){ 
    $query = mysql_query("SELECT * FROM stories WHERE title = '".htmlentities($items['title'], 
          ENT_QUOTES)."'") or die(mysql_error()); 
    $num = mysql_num_rows($query); 
    if($num > 0){ 
        echo $items['title']." already exists!<br />"; 
    } 
    else { 
        $items2['description'] = unhtmlspecialchars ($items['description']); 
         

        if (mysql_query("INSERT INTO stories VALUES('', '".htmlentities($items['title'],  
                 ENT_QUOTES)."', '".htmlentities($items2['description'], ENT_QUOTES)."',  
                  '".htmlentities($items['link'],ENT_QUOTES)."')") or die(mysql_error())){ 
        echo $items['title']." was added!<br />"; 
        } 
    } 
} 

?>

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:32

Janoz

Moderator Devschuur®

!litemod

Hier staat wel iets over deze tag. het hoe en waarom. Het was de eerste hit die ik tegenkwam toen ik op google zocht. Wat gaat er mis? Wat lukt er niet? Dat je het al 2 dagen aan het proberen bent zegt mij helemaal niks. Het is makkelijker wanneer je verteld wat je aan het proberen bent. Dat staat ook allemaal in de quickstart waarnaar in je vorige topic verwezen werd.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • mace
  • Registratie: Juni 2003
  • Laatst online: 01-12 16:53

mace

Sapere Aude

komt het misschien omdat je de dubbele punt niet unencode?


Dus bij:

PHP:
1
2
3
4
5
6
7
8
9
10
function unhtmlspecialchars( $string )
    { 
        $string = str_replace ( '&amp;', '&', $string ); 
        $string = str_replace ( ''', '\'', $string ); 
        $string = str_replace ( '&quot;', '\"', $string ); 
        $string = str_replace ( '&lt;', '<', $string ); 
        $string = str_replace ( '&gt;', '>', $string ); 
         
        return $string; 
    }


het volgende toevoegen:

PHP:
1
        $string = str_replace ( ':', ':', $string );

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Indenteer je code eens netjes, want dit leest gewoon niet lekker. ;) Zodra je commentaar nodig hebt als '//end opening element ', geef je toe dat je slecht leesbare code schrijft. De oplossing is dan de code netter maken, ipv dit soort commentaar neerpennen.

Verder doe je er goed aan om gewoon de strings waar je mee werkt eens letterlijk te bekijken. Welke karakters komen er precies voor, welke htmlentities worden er precies gebruikt etc. etc. Als je strings letterlijk bekijkt, moet je ook kunnen zien wat er niet klopt aan de 2e parameter van deze replace:
PHP:
17
$string = str_replace ( '&quot;', '\"', $string );


Daarbij is het dus ook handig om je meer in dit soort string functies te verdiepen. Zo is htmlentities() niet de ideale anti mysql injection functie; daarvoor is er mysql_real_escape_string(). Htmlentities is meer iets voor de presentatie laag, als je een string uit de db trekt en in html wil zetten kan je er op het geschikte punt htmlentities over heen halen. Als je netjes met dit soort functies omgaat, heb je ook minder snel functies als unhtmlspecialchars() (of de sinds PHP 5.1.0 aanwezige htmlspecialchars_decode()) nodig. :)

{signature}


  • ilovetechno
  • Registratie: Oktober 2001
  • Laatst online: 24-11 02:36
Janoz schreef op zaterdag 19 mei 2007 @ 12:06:
Hier staat wel iets over deze tag. het hoe en waarom. Het was de eerste hit die ik tegenkwam toen ik op google zocht. Wat gaat er mis? Wat lukt er niet? Dat je het al 2 dagen aan het proberen bent zegt mij helemaal niks. Het is makkelijker wanneer je verteld wat je aan het proberen bent. Dat staat ook allemaal in de quickstart waarnaar in je vorige topic verwezen werd.
Wat ik aan het proberen ben is het volgende:

Ik heb een rij extra gemaakt in de tabel genaamd contentenc. Verder heb ik de volgende regel gewijzigd:

PHP:
1
if($tag == "TITLE" || $tag == "DESCRIPTION" || $tag="CONTENT:ENCODED" || $tag == "THUMB" || $tag == "LINK"){


Maar helaas werkt deze niet. De volgende ook niet:

PHP:
1
if($tag == "TITLE" || $tag == "DESCRIPTION" || $tag="CONTENT:ENCODED" || $tag == "THUMB" || $tag == "LINK"){


PHP:
1
if($tag == "TITLE" || $tag == "DESCRIPTION" || $tag="CONTENT" || $tag == "THUMB" || $tag == "LINK"){


De insert van de DB heb ik als volgt gewijzigd.

PHP:
1
2
3
4
        if (mysql_query("INSERT INTO test VALUES('', '".htmlentities($items['title'], 
                 ENT_QUOTES)."', '".htmlentities($items2['description'], ENT_QUOTES)."', '".htmlentities($items['content'], ENT_QUOTES)."',  
                  '".htmlentities($items['link'],ENT_QUOTES)."', '".$cat."')") or die(mysql_error())){
        echo $items['title']." was added!<br />";


De code zoals door MaCe1337 aangegeven heb ik toegevoed. Helaas bied dit ook geen oplossing.
PHP:
1
$string = str_replace ( ':', ':', $string );


Heeft er nog iemand ideeen? :/

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

Waarom probeer je het wiel opnieuw uit te vinden en pak je niet gewoon een al bestaande rss parser class :?

Stop uploading passwords to Github!


Verwijderd

Is het niet handiger om eerst te bekijken wat je precies ontvangt in plaats van zomaar in het wild if statements te gaan gokken? :) Lijkt me kwestie van debuggen?

  • ilovetechno
  • Registratie: Oktober 2001
  • Laatst online: 24-11 02:36
:9
Verwijderd schreef op maandag 21 mei 2007 @ 10:46:
Is het niet handiger om eerst te bekijken wat je precies ontvangt in plaats van zomaar in het wild if statements te gaan gokken? :) Lijkt me kwestie van debuggen?
Dit heb ik dus gedaan door een truncate in te bouwen alle inhoud van de tags te echo'en. Het vreemde is dat als ik het veld description verwijder en deze vervang door <content:encoded>. Dat hij tevens de link niet meer vult. Het zal wel heel makkelijk op te lossen zijn maar ik zie alleen niet hoe. Met Google kom ik ook niet echt verder dan kant en klare classes.

PHP:
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?php

$connection = mysql_connect("*",
                            "*_*",
                            "*");
mysql_select_db("*_RSS", $connection);

$counter = 0;
$type = 0;
$tag = "";
$itemInfo = array();
$channelInfo = array();
//from html_entity_decode() manual page
function unhtmlspecialchars( $string )
    {
        $string = str_replace ( '&amp;', '&', $string );
        $string = str_replace ( ''', '\'', $string );
        $string = str_replace ( '&quot;', '\"', $string );
        $string = str_replace ( '&lt;', '<', $string );
        $string = str_replace ( '&gt;', '>', $string );
        $string = str_replace ( ':', ':', $string ); 
        
        return $string;
    }

function opening_element($xmlParser, $name, $attribute){



global $tag, $type;

$tag = $name;

if($name == "CHANNEL"){
$type = 1;
}
else if($name == "ITEM"){
$type = 2;
}

}//end opening element

function closing_element($xmlParser, $name){

global $tag, $type, $counter;

$tag = "";
if($name == "ITEM"){
$type = 0;
$counter++;
}
else if($name == "CHANNEL"){
$type = 0;
}
}//end closing_element

function c_data($xmlParser, $data){

global $tag, $type, $channelInfo, $itemInfo, $counter;

$data = trim(htmlspecialchars($data));

if($tag == "TITLE" || $tag="CONTENT:ENCODED" || $tag == "THUMB" || $tag == "LINK"){
if($type == 1){

$channelInfo[strtolower($tag)] = $data;

}//end checking channel
else if($type == 2){

$itemInfo[$counter][strtolower($tag)] .= $data;

}//end checking for item
}//end checking tag
}//end cdata funct

$xmlParser = xml_parser_create();

xml_parser_set_option($xmlParser, XML_OPTION_CASE_FOLDING, TRUE);
xml_parser_set_option($xmlParser, XML_OPTION_SKIP_WHITE, TRUE);

xml_set_element_handler($xmlParser, "opening_element", "closing_element");
xml_set_character_data_handler($xmlParser, "c_data");

$fp = file($_GET['rss']);
$cat = "boobs";
foreach($fp as $line){
if(!xml_parse($xmlParser, $line)){
die("Could not parse file.");
}
}

foreach($itemInfo as $items){
    $query = mysql_query("SELECT * FROM test WHERE title = '".htmlentities($items['title'],
          ENT_QUOTES)."'") or die(mysql_error());
    $num = mysql_num_rows($query);
    if($num > 0){
        echo $items['link']." already exists!<br />";
        echo $items['title']." already exists!<br />";
        echo $items['content'];
    }
    else {
        $items2['description'] = unhtmlspecialchars ($items['description']);
        

        if (mysql_query("INSERT INTO test VALUES('', '".htmlentities($items['title'], 
                 ENT_QUOTES)."', '".htmlentities($items['content'], ENT_QUOTES)."',  
                  '".htmlentities($items['link'],ENT_QUOTES)."', '".$cat."')") or die(mysql_error())){
        echo $items['title']." was added!<br />";
        }
    }
}

?>
SchizoDuckie schreef op maandag 21 mei 2007 @ 10:45:
Waarom probeer je het wiel opnieuw uit te vinden en pak je niet gewoon een al bestaande rss parser class :?
Ik wil gewoon grootendeels zelf mijn code maken. Dit werkt prima alleen die ene tag niet. Dat is voor mij natuurlijk geen reden om te stoppen en een bestaand iets te gebruiken.

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Reageren op mijn post vind ik wel een leuk idee. :P

{signature}


  • ilovetechno
  • Registratie: Oktober 2001
  • Laatst online: 24-11 02:36
Voila :)
Voutloos schreef op zaterdag 19 mei 2007 @ 12:37:
Indenteer je code eens netjes, want dit leest gewoon niet lekker. ;) Zodra je commentaar nodig hebt als '//end opening element ', geef je toe dat je slecht leesbare code schrijft. De oplossing is dan de code netter maken, ipv dit soort commentaar neerpennen.

Verder doe je er goed aan om gewoon de strings waar je mee werkt eens letterlijk te bekijken. Welke karakters komen er precies voor, welke htmlentities worden er precies gebruikt etc. etc. Als je strings letterlijk bekijkt, moet je ook kunnen zien wat er niet klopt aan de 2e parameter van deze replace:
PHP:
17
$string = str_replace ( '&quot;', '\"', $string );


Daarbij is het dus ook handig om je meer in dit soort string functies te verdiepen. Zo is htmlentities() niet de ideale anti mysql injection functie; daarvoor is er mysql_real_escape_string(). Htmlentities is meer iets voor de presentatie laag, als je een string uit de db trekt en in html wil zetten kan je er op het geschikte punt htmlentities over heen halen. Als je netjes met dit soort functies omgaat, heb je ook minder snel functies als unhtmlspecialchars() (of de sinds PHP 5.1.0 aanwezige htmlspecialchars_decode()) nodig. :)
Het commentaar zal ik iig bekijken en aanpassen. Ik begrijp dat dit wat summier is. Ik maak altijd wel een soort van PSD
Een quote is een " teken. Ik zie niet wat ik hier fout doe. Alleen geeft hij hier een enter mee. :?

Ik zal tevens de mySQL functies gaan bekijken om dit beter op te lossen.

  • Spockz
  • Registratie: Augustus 2003
  • Laatst online: 19-11 13:44

Spockz

Live and Let Live

Je vervangt daar nu elke " met een \". Omdat je ' als opening gebruikt moet je de " niet nog eens escapen.

C'est le ton qui fait la musique. | Blog | @linkedin
R8 | 18-55 IS | 50mm 1.8 2 | 70-200 2.8 APO EX HSM | 85 1.8


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
ilovetechno schreef op maandag 21 mei 2007 @ 13:31:
Een quote is een " teken. Ik zie niet wat ik hier fout doe. Alleen geeft hij hier een enter mee. :?
Enters bestaan niet, hoogstens carriage return ( "\r" ) en newline ( "\n" ) karakters. :P Of bedoel je die backslash? Hoe dan ook, die backslash is dus fout. :P Als je op een fatsoenlijke manier je strings debugt, had je kunnen waarnemen dat die quote html entity vervangen wordt door \" (inc. backslash dus). Mede omdat je dus niet begrijpt dat die backslash fout is, begon ik te zeuren over je string en escaping kennis. :)

{signature}

Pagina: 1