8791 sujets

Développement web côté serveur, CMS

Bonjour ...

En premier, je présente une partie de code xml :


<style:style style:name="T(.*)" style:family="text">
  <style:text-properties style:text-position="(super|sup) 58%"/>
</style:style>

<text:span text:style-name="T(.*)">blabla</text:span>


Pour ceux qui ne connaissent pas, et pour les autres, ce code est ce que génère le format ODF pour gérer le positionnement en tant qu'indice ou exposant... (sachant que les parenthèses, c'est moi qui vous les ai mises, afin de vous montrer les différentes possibilités)
Bref, ce n'est pas fait simplement !

Donc, il me faut analyser le code XML :
- pour repérer tous les attributs style-name, de l'élément style:style, commençant par T - et mieux suivi d'un ou plusieurs chiffres - correspondant à une déclaration de l'attribut style:text-position, de l'élément enfant style:text-properties ...
- puis repérer l'attribut text:style-name, de l'élément text:span correspondant,
- afin de transformer cet élément text:span en text:sup ou text:sub ...
(La feuille XSL se chargeant de transformer en équivalent HTML. Smiley langue )

J'essaye de démarrer avec ce code PHP, mais cela ne fonctionne pas !

preg_match_all('/<style:style style:name="T(.*?)" style:family="text"><style:text-properties style:text-position="(.*?)"/><\/style:style>/Us',$this->content,$this->match);


ou celui-ci, moins restrictif :

preg_match_all('/<style:style style:name="T(.*?)" style:family="text">(.*)<\/style:style>/Us',$this->content,$this->match);


si je fais un var_dump de la variable match, elle est vide ...

Quelqu'un pourrait-il m'aider, svp ?
Modifié par ste (27 Jul 2007 - 11:08)
Je penses que tu peux faire ça avec XSL, mais les expressions régulières je connais mieux. Donc voyons avec celles-ci.

Si l'on regarde ton code:
'/<style:style style:name="T(.*?)" style:family="text"><style:text-properties style:text-position="(.*?)"/><\/style:style>/Us'

Il y a plusieurs choses à modifier:
-le délimiteur qui est présent dans ton expression et donc oblige à ajouter des antislashes.
-l'utilisation de .*? ne signifie rien, il faudrait utiliser .* ou .?
-il est inutile d'utiliser le point quand on peut faire autrement car il consomme beaucoup de ressources.
-les espace indiqués en dur qui risquent de fausser la recherche.

Ce qui donne:
'`<style:style style:name="(T[0-9]+)" style:family="text">\s*<style:text-properties style:text-position="([^"]+)"/>\s*</style:style>`'
Bon, je viens en fait d'y arriver - certainement, très improprement - :


		if(preg_match_all('`<style:style style:name="T([0-9]+)" style:family="text"><style:text-properties style:text-position="(.*?)"/></style:style>`es',$this->content,$this->match)) {
			
			foreach($this->match[1] as $k => $v) {
				$this->position['name'][$k] = $v;
				$this->position['string'][$k] = substr($this->match[2][$k], 0, 3);
			}
		}
		
		if(preg_match_all('`<text:span text:style-name="T([0-9]+)">(.*)</text:span>`Us', $this->content,$this->match)) {
			
			foreach($this->match[1] as $k => $v) {
				if(in_array($v,$this->position['name'])) {
					foreach($this->position['name'] as $k2 => $v2) {
						if($v2 == $v) {
							$this->position['search'][$k2] = '<text:span text:style-name="T'.$this->position['name'][$k2].'">'.$this->match[2][$k].'</text:span>';
							$this->position['replace'][$k2] = '<text:'.$this->position['string'][$k2].'>'.$this->match[2][$k].'</text:'.$this->position['string'][$k2].'>';
						}
					}
				}
			}
		}
		
		if(!empty($this->position['search']) && is_array($this->position['search'])) {
			foreach($this->position['search'] as $k => $v) {
				$this->content = str_replace($v, $this->position['replace'][$k], $this->content);
			}
		


Alors, avant de me faire gronder par Necromantik - que je remercie, en passant -, je n'ai pas implémenter toutes tes recommandations ; j'explique pourquoi :

- Alors que tu me demandes de remplacer (.*?) par ([^"]+), je ne sais pas pourquoi, mais avec ton masque, il me manque une recherche - la dernière - ... je reste tout ouïe afin de comprendre le pourquoi !?!
- Je n'ai pas rajouté non plus le masque \s*, parce que travaillant sur le xml ODF, je sais qu'il n'y a AUCUN espace entre chaque élément XML.

Pour finir, je me doute que mon code est complexe, et qu'il est certainement possible de faire autrement, dans ce cas, je reste sincèrement ouvert aux suggestions offertes ! Smiley langue
ste a écrit :
- Alors que tu me demandes de remplacer (.*?) par ([^"]+), je ne sais pas pourquoi, mais avec ton masque, il me manque une recherche - la dernière - ... je reste tout ouïe afin de comprendre le pourquoi !?!

Le motif ([^"]+) va chercher au moins un caractère autre que le guillemet, il y aurait 2 cas ou il ne marche pas: s'il y a un guillement dans le contenu de l'attribut ou si l'attribut est vide.
Dans le premier cas je crois pas que c'est valide xml, dans le deuxième il suffit de remplacer le + par un *.


ste a écrit :
- Je n'ai pas rajouté non plus le masque \s*, parce que travaillant sur le xml ODF, je sais qu'il n'y a AUCUN espace entre chaque élément XML.

Logique, je me basais sur le code donné qui lui en comprend. Effectivement dans ce cas ils ne servent à rien Smiley cligne .


Et de rien.
Necromantik a écrit :

Le motif ([^"]+) va chercher au moins un caractère autre que le guillemet, il y aurait 2 cas ou il ne marche pas: s'il y a un guillement dans le contenu de l'attribut ou si l'attribut est vide.
Dans le premier cas je crois pas que c'est valide xml, dans le deuxième il suffit de remplacer le + par un *.

(...)


Justement, le contenu de l'attribut, sur le texte que je teste est :
- 2
- Indice
- Exposant

'2' et 'Exposant' étant du texte mis en exposant dans le document ODF de test, et 'Indice' étant du texte mis en indice.
Bien sûr, pour tester, je peux mettre tout autre caractère soit en indice, soit en exposant ...

Si je mets l'une ou l'autre version du masque que tu m'indique, je n'arrive pas à un résultat complet, en ce sens où le texte 'Exposant' n'est pas du tout listé comme devant être manipulé.

(Entre-tps, je vais me replonger dans la doc de php.net, pour essayer de mieux comprendre cette histoire de masque...)

PS : À ce propos, la doc de php.net informe sur sa page syntaxe des masques :
a écrit :

Cependant, un quantificateur suivi d'un point d'interrogation cesse d'être gourmand, et au contraire, ne recherche que le nombre minimum de répétition. Dans ces conditions, le masque /\*.*?\*/ trouvera bien les commentaires du code C. La signification des autres quantificateurs n'est pas changée. Attention à ne pas confondre l'utilisation du point d'interrogation ici avec son utilisation comme quantificateur lui-même. À cause de cette ambiguïté, il peut apparaître des situations où il faut le doubler : \d??\d. Ce masque va tenter de lire un seul chiffre, mais, le cas échéant, il acceptera 2 chiffres pour permettre à la recherche d'aboutir.

... est à remarquer la syntaxe du masque ! (et sa signification, bien sûr Smiley murf )

Modifié par ste (28 Jul 2007 - 18:54)
Pour tester ça il me faudrait ton code xml qui bug car en théorie ça marche... Smiley lol


ste a écrit :
PS : À ce propos, la doc de php.net informe sur sa page syntaxe des masques : [...]

Tiens je connaissais pas cette syntax là, interessant *note* merci Smiley cligne



Si tu cherche de la documentation: http://www.expreg.com/ {fr}
Beh, si vraiment ça t'intéresse, dès que j'ai fini ma nouvelle mouture de la lib odt2xhtml, et que j'ai publié, je t'en informe, et te donne les élèments adhocs...

Merci pour le site expreg !
Necromantik a écrit :
Pour tester ça il me faudrait ton code xml qui bug car en théorie ça marche... Smiley lol
(...)


@Necromantik :
J'ai réfléchi durant ce week-end, que le fameux xml se détruisait... normalement Smiley langue
Donc, j'ai gardé une version de ce fichier qui est disponible sur odt2xhtml.xml.

Voili, voilou
Necromantik a écrit :
Je note le lien et je regarde prochainement Smiley rolleyes .


As you want ... thanks Smiley lol
Après coup d'oeil voici ce que ça donne.

Si j'utilise ton filtre je reçoit 3 résultats:
    [0] => Array
        (
            [0] => <style:style style:name="T7" style:family="text"><style:text-properties style:text-position="super 58%"/></style:style>
            [1] => <style:style style:name="T8" style:family="text"><style:text-properties style:text-position="super 58%" fo:background-color="transparent"/></style:style>
            [2] => <style:style style:name="T9" style:family="text"><style:text-properties style:text-position="sub 58%"/></style:style>
        )

    [1] => Array
        (
            [0] => 7
            [1] => 8
            [2] => 9
        )

    [2] => Array
        (
            [0] => super 58%
            [1] => super 58%" fo:background-color="transparent
            [2] => sub 58%
        )


Si j'utilise l'autre motif j'en obtient effectivement que 2, cela vient du fait qu'un des résultats possède un attribut fo:background.

Mais avec ton masque cet attribut se retrouve dans la sortie.
Pour obtenir les 3 résultats sans le fo:background j'ai utilisé:
'`<style:style style:name="T([0-9]+)" style:family="text"><style:text-properties style:text-position="([^"]+)"[^>]*/></style:style>`
Necromantik a écrit :
Après coup d'oeil voici ce que ça donne.

Si j'utilise ton filtre je reçoit 3 résultats:

En effet, c'est ce que cela restitue Smiley langue

a écrit :

Si j'utilise l'autre motif j'en obtient effectivement que 2, cela vient du fait qu'un des résultats possède un attribut fo:background.

Mais avec ton masque cet attribut se retrouve dans la sortie.
Pour obtenir les 3 résultats sans le fo:background j'ai utilisé:
'`<style:style style:name="T([0-9]+)" style:family="text"><style:text-properties style:text-position="([^"]+)"[^>]*/></style:style>`


OUi, en fait, avec mon masque, il va chercher jusqu'au dernier " avant les symboles /> ...
Ce que ton masque évite apparement !

Je le garde sous le coude ...

Merci beaucoup, à toi Smiley langue

PS : À tout hasard, tu n'aurais pas une idée concernant ce soucis : http://forum.alsacreations.com/topic-3-27828-1-2ble-ajout-de-lattribut-xmlns-dans-lelement-html.html
De rien.
Concernant ton autre sujet: non aucune idée, si ce n'est qu'en php5 le namespace est peut-être ajouté automatiquement.