simple_load_xml et caracteres speciaux.

Mammouth du PHP | 504 Messages

10 mars 2014, 22:31

Bonjour a tous,

j'ai une ligne dans un xml qui me pose un soucis et qui fait planter le chargement de mon script:
<Via_Futebol_Clube_do_Porto__Estádio__Entrada_Nascente__15__3º>Indirizzo evento</Via_Futebol_Clube_do_Porto__Estádio__Entrada_Nascente__15__3º>
Je recupere le flux que je charge avec simple_load_xml. J'ai besoin de recuperer le nom de la balise donc je parse comme suit

foreach ($product->fields->children() as $child){
if ($child == 'Indirizzo evento') {
echo $child.': ';
echo $adresse = str_replace('_',' ', $child->getName());
}
}

ça fonctionne sauf quand il ya la presence de: º. ça fait planter le chargement et me retourne false sur un var_dump.

Comment faire ? Merci a vous.

ViPHP
xTG
ViPHP | 7331 Messages

11 mars 2014, 09:24

Est-ce que ton php est configuré pour l'utf-8 ?
Ton fichier XML est-il enregistré en utf-8 ?

Mammouth du PHP | 504 Messages

11 mars 2014, 10:18

Bjr Xtg,

Oui, les deux sont bien en utf_8. C'est ce que je trouve bizarre. su je retire le °, cela fonctionne.

Voici l'extrait du flux:
<product>
        <name>FC Porto - Benfica</name>
        <productUrl>xxxxxxxxxx</productUrl>
        <imageUrl>xxxxxxxxxx</imageUrl>
        <description>FC Porto - Benfica</description>
        <price>63.00</price>
        <currency>EUR</currency>
        <TDProductId>1474210955</TDProductId>
        <TDCategoryID>86</TDCategoryID>
        <TDCategoryName>Films et théatre</TDCategoryName>
        <merchantCategoryName>xxxxxxxx</merchantCategoryName>
        <programLogoPath>xxxxxxxxxx</programLogoPath>
        <programId>119081</programId>
        <advertiserProductUrl>xxxxxxxxxxxx</advertiserProductUrl>
        <fields>
            <_014-05-11T20_00_00>Data evento</_014-05-11T20_00_00>
            <_350-415>CAP evento</_350-415>
            <_85>FieldValue</_85>
            <Dragon_Stadium>Luogo evento</Dragon_Stadium>
            <Porto>Citta evento</Porto>
            <PT>Nazione evento</PT>
            <Via_Futebol_Clube_do_Porto__Estádio__Entrada_Nascente__15__3º>Indirizzo evento</Via_Futebol_Clube_do_Porto__Estádio__Entrada_Nascente__15__3º>
        </fields>
    </product>
et mon script:
$xml = simplexml_load_file('test.xml');

var_dump($xml);


foreach ($xml->product as $product) {

print "<br /><br />\n";
print "{$product->name}<br />\n";
print "{$product->productUrl}<br />\n";
print "{$product->description}<br />\n";
print "{$product->imageUrl}<br />\n";
print "{$product->price}<br />\n";
print "{$product->currency}<br />\n";
print "{$product->TDCategoryName}<br />\n";
print "{$product->TDProductId}<br />\n";

foreach ($product->fields->children() as $child){
echo $child.': ';    
echo $balise=$child->getName() . "<br />";

if ($child == 'Nazione evento') {
echo $child.': '; 
echo $country = $child->getName();
}

if ($child == 'Data evento') {
echo $child.': '; 
 
$date = str_replace('_014','2014', $child->getName());
echo $date = str_replace('_',':', $date);
} 

if ($child == 'Indirizzo evento') {
echo $child.': '; 
echo $adresse = str_replace('_',' ', $child->getName());
} 

if ($child == 'Citta evento') {
echo $child.': '; 
$city = str_replace('_',' ', $child->getName());
echo $city =' | '.$city.' | FR';
}  

if ($child == 'Luogo evento') {
echo $child.': '; 
echo $Lieu = str_replace('_',' ', $child->getName());
}  
    
}
}
Je suis dessus depuis 24 heures toujours pas trouvé une issue. :?

ViPHP
xTG
ViPHP | 7331 Messages

11 mars 2014, 14:28

Et si tu remplaces l'élément name par namé as-tu aussi le problème ?

Mammouth du PHP | 504 Messages

11 mars 2014, 14:45

En fait, j'ai testé en enlevant cette ligne dans le xml:
<Via_Futebol_Clube_do_Porto__Estádio__Entrada_Nascente__15__3º>Indirizzo evento</Via_Futebol_Clube_do_Porto__Estádio__Entrada_Nascente__15__3º>
Le script fonctionne.

2eme essai sans le °:
<Via_Futebol_Clube_do_Porto__Estádio__Entrada_Nascente__15__3>Indirizzo evento</Via_Futebol_Clube_do_Porto__Estádio__Entrada_Nascente__15__3>
Cela fonctionne aussi.

Le ° pose donc un probleme à simple_xml. Je vais remplacé name par namé mais je ne crois pas que ça va changer grand chose.

ViPHP
xTG
ViPHP | 7331 Messages

11 mars 2014, 17:31

C'est surtout pour être sûr que ce n'est pas un problème d'encodage.
Mais je viens de voir que tu avais un "à" qui était correctement interprété, donc tu as bien une configuration utf-8 propre.
Quand on lit la RFC ce caractère devrait être autorisé, peut être un bug de la librairie du coup ?
On peut lire par exemple dans les commentaires de la fonction :
que cette personne a eu un souci avec le caractère "-" qui n'est pas autorisé.

Tu peux regarder du côté de : http://fr2.php.net/manual/fr/function.l ... errors.php
Pour être sûr de ce qui ne lui plaît pas.

Eléphant du PHP | 453 Messages

11 mars 2014, 18:28

Salut,

C'est surtout que le document n'est pas valide ! Quand je lis ce code, il y a à boire et à manger. Je suis pratiquement certain que Dom le rejette à l'instanciation/chargement.

Cet élément devrait être un textNode (<Via_Futebol_Clube_do_Porto__Estádio__Entrada_Nascente__15__3º></Via_Futebol_Clube_do_Porto__Estádio__Entrada_Nascente__15__3º>) -> (<el>Via_Futebol_Clube_do_Porto__Estádio__Entrada_Nascente__15__3º</el>) ou la valeur d'un attribut : (<el val="Via_Futebol_Clube_do_Porto__Estádio__Entrada_Nascente__15__3º">du texte</el>)

Si tu n'as pas la main sur le doc xml, il va falloir le parser différemment :

Récupérer le contenu brute
redéfinir et rendre le document valide. Ce genre de fonction devrait peut être t'aider pour nettoyer ce {§%µ#`\^=}
function strtoslug($string, $replacement = '_') {
		$quotedReplacement = preg_quote($replacement, '/');
$transliteration = array(
		'/ä|æ|ǽ/' => 'ae',
		'/ö|œ/' => 'oe',
		'/ü/' => 'ue',
		'/Ä/' => 'Ae',
		'/Ü/' => 'Ue',
		'/Ö/' => 'Oe',
		'/À|Á|Â|Ã|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A',
		'/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a',
		'/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
		'/ç|ć|ĉ|ċ|č/' => 'c',
		'/Ð|Ď|Đ/' => 'D',
		'/ð|ď|đ/' => 'd',
		'/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E',
		'/è|é|ê|ë|ē|ĕ|ė|ę|ě/' => 'e',
		'/Ĝ|Ğ|Ġ|Ģ/' => 'G',
		'/ĝ|ğ|ġ|ģ/' => 'g',
		'/Ĥ|Ħ/' => 'H',
		'/ĥ|ħ/' => 'h',
		'/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ/' => 'I',
		'/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/' => 'i',
		'/Ĵ/' => 'J',
		'/ĵ/' => 'j',
		'/Ķ/' => 'K',
		'/ķ/' => 'k',
		'/Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L',
		'/ĺ|ļ|ľ|ŀ|ł/' => 'l',
		'/Ñ|Ń|Ņ|Ň/' => 'N',
		'/ñ|ń|ņ|ň|ʼn/' => 'n',
		'/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O',
		'/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o',
		'/Ŕ|Ŗ|Ř/' => 'R',
		'/ŕ|ŗ|ř/' => 'r',
		'/Ś|Ŝ|Ş|Ș|Š/' => 'S',
		'/ś|ŝ|ş|ș|š|ſ/' => 's',
		'/Ţ|Ț|Ť|Ŧ/' => 'T',
		'/ţ|ț|ť|ŧ/' => 't',
		'/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U',
		'/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u',
		'/Ý|Ÿ|Ŷ/' => 'Y',
		'/ý|ÿ|ŷ/' => 'y',
		'/Ŵ/' => 'W',
		'/ŵ/' => 'w',
		'/Ź|Ż|Ž/' => 'Z',
		'/ź|ż|ž/' => 'z',
		'/Æ|Ǽ/' => 'AE',
		'/ß/' => 'ss',
		'/IJ/' => 'IJ',
		'/ij/' => 'ij',
		'/Œ/' => 'OE',
		'/ƒ/' => 'f'
	);
		$merge = array(
			'/[^\s\p{Zs}\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]/mu' => ' ',
			'/[\s\p{Zs}]+/mu' => $replacement,
			sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '',
		);

		$map = $transliteration + $merge;
		return preg_replace(array_keys($map), array_values($map), $string);
	}
	
	$str = 'Via_Futebol_Clube_do_Porto__Estádio__Entrada_Nascente__15__3º';
	echo strtoslug(strtolower($str),'');
edit :
pour un bout de piste :
$xmlBrute = file_get_contents('xml-pourri.xml');
	$posFieldsEntrant = strpos($xmlBrute,'<fields>');
	$posFieldsSortant = strpos($xmlBrute,'</fields>');
	
	$docXml = substr($xmlBrute,0,$posFieldsEntrant ).'</product>';
	

$xml = simplexml_load_string($docXml);
echo $xml->name;
La Tux attitude avec les kiw'z syou plait
Komodo Edit - Inkscape - Dia

Mammouth du PHP | 504 Messages

12 mars 2014, 06:42

Merci @Niuxe pour ton info.

Je teste ça de ce pas. Comme tu l'évoques, je n'ai pas la main sur le xml du départ et effectivement leur xml est pourri meme dans sa structure de base (mettre des infos variables en nom de balise, c'est assez à l'envers comme vu d'esprit).

Je vous tiens au courant.