Page 1 sur 1
[..] Fonction _FileWriteToLine problème d'encodage
Posté : jeu. 24 févr. 2011 18:22
par corrs78
Bonsoir,
j'ai un problème très embêtant.
Je dois ecraser une ligne spécifique d'un fichier de configuration xml. (la ligne 3 pour être précis).
j'utilise donc la fonction appropriée
Code : Tout sélectionner
_FileWriteToLine("C:\Videomotion\Preferences.xml", 3, "ma nouvelle ligne", 1)
-> ma ligne est bien remplacée, mais le problème, c'est qu'une autre ligne de mon fichier comportant des caractères accentués est réencodée de cette sorte :
<VIDEO_DEVICE>Périphérique vidéo USB</VIDEO_DEVICE>
De cette façon mon fichier xml n'est plus interprété correctement par mon logiciel.
Auriez vous une idée pour corriger ce problème ?
Merci à vous
Re: [..] Fonction _FileWriteToLine problème d'encodage
Posté : ven. 25 févr. 2011 00:54
par GaRydelaMer
Bonjour
Utilisé les objets COM
En l'occurrence MSXML, et XPath pour atteindre les Noeuds
► Afficher le texte
Code : Tout sélectionner
Local $URL = "test.xml"
Local $XPath = "//VIDEO_DEVICE"
Local $NewValue = "Périphérique vidéo USB"
; Je créer un Objet MSXML et je l'initialise
Local $xmlDoc = ObjCreate("Msxml2.DOMDocument.6.0")
If Not IsObj($xmlDoc) Then
ConsoleWrite("Erreur N°1 Impossible de créer un objet MSXML." & @CRLF)
$xmlDoc = 0
Exit 1
EndIf
; J'ouvre le fichier xml @ lire: Chemin local ou URL
$xmlDoc.async = False
$xmlDoc.preserveWhiteSpace = True
$xmlDoc.load($URL)
If $xmlDoc.ParseError.ErrorCode <> 0 Then
; Je vérifie si il y a des erreurs à l'ouverture
ConsoleWrite("Erreur N°2 Load: URL: """ & $URL & """." & @CRLF & StringStripWS($xmlDoc.ParseError.Reason, 7) & @CRLF)
$xmlDoc = 0
Exit 2
EndIf
; Je me positionne à un Noeud du l'arbre xml c'est un objet: $Node
If $XPath = "" Then
ConsoleWrite("Erreur N°3 SelectSingleNode: XPath vide." & @CRLF)
$xmlDoc = 0
Exit 3
EndIf
$xmlDoc.setProperty("SelectionLanguage", "XPath")
Local $Node = $xmlDoc.selectSingleNode($XPath)
If Not IsObj($Node) Then
ConsoleWrite("Erreur N°4 Aucun Noeud atteint aucune modification: XPath """ & $XPath & """." & @CRLF & StringStripWS($xmlDoc.ParseError.Reason, 7) & @CRLF)
$xmlDoc = 0
Exit 4
Else
; Je lit et affiche dans la console le xml parsé du fichier
ConsoleWrite("URL du fichier xml: """ & $xmlDoc.url & """" & @CRLF)
ConsoleWrite("Contenu actuel du Noeud: " & $Node.text & @CRLF)
ConsoleWrite("Contenu du xml:" & @CRLF & $xmlDoc.xml & @CRLF & "+++++++++++++" & @CRLF)
; J'écris la valeur du noeud: le text
$Node.text = $NewValue
ConsoleWrite("Nouveau contenu du Noeud: " & $Node.text & @CRLF)
ConsoleWrite("Contenu du xml:" & @CRLF & $xmlDoc.xml & @CRLF & "+++++++++++++" & @CRLF)
; je sauvegarde la mofification, en récuperant l'url du fichier
$xmlDoc.Save($xmlDoc.url)
EndIf
; Je recharge le fichier et j'affiche le contenu pour vérifier le changement
$xmlDoc.load($URL)
ConsoleWrite("Contenu du fichier xml:" & @CRLF & $xmlDoc.xml & @CRLF & "+++++++++++++" & @CRLF)
$xmlDoc = 0
Exit 0
► Afficher le texteFichier XML de test encoder avec NotPad++ en UTF8(sans bom)
Code : Tout sélectionner
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<VIDEO_DEVICE>Périphérique vidéo</VIDEO_DEVICE>
<AUDIO_DEVICE>Périphérique Audio USB</AUDIO_DEVICE>
</Root>
► Afficher le texteAprés test
Code : Tout sélectionner
>Running:(3.3.6.0):C:\Program Files (x86)\AutoIt3\autoit3_x64.exe "X:\_Sources\zz.au3"
URL du fichier xml: "file:///X:/_Sources/test.xml"
Contenu actuel du Noeud: Périphérique vidéo
Contenu du xml:
<?xml version="1.0"?>
<Root>
<VIDEO_DEVICE>Périphérique vidéo</VIDEO_DEVICE>
<AUDIO_DEVICE>Périphérique Audio USB</AUDIO_DEVICE>
</Root>
+++++++++++++
Nouveau contenu du Noeud: Périphérique vidéo USB
Contenu du xml:
<?xml version="1.0"?>
<Root>
<VIDEO_DEVICE>Périphérique vidéo USB</VIDEO_DEVICE>
<AUDIO_DEVICE>Périphérique Audio USB</AUDIO_DEVICE>
</Root>
+++++++++++++
Contenu du fichier xml:
<?xml version="1.0"?>
<Root>
<VIDEO_DEVICE>Périphérique vidéo USB</VIDEO_DEVICE>
<AUDIO_DEVICE>Périphérique Audio USB</AUDIO_DEVICE>
</Root>
+++++++++++++
+>00:50:39 AutoIT3.exe ended.rc:0
>Exit code: 0 Time: 1.965
Fais en 1 fonction si tu as plusieurs modifications à faire je t'ai mis la gestion des erreurs et les commentaires de chaque ligne.
Bien sur après à toi d'approfondir l'utilisation de MSXML. Tu trouveras l'aide en anglais msxml 4.0 SDK.
Et regarder du coté de l'UDF MSXML.
Re: [..] Fonction _FileWriteToLine problème d'encodage
Posté : ven. 25 févr. 2011 08:15
par FernandG
Bonjour,
En complément de la réponse de
GaRydelaMer,
corrs78 a écrit :une autre ligne de mon fichier comportant des caractères accentués est réencodée de cette sorte :
<VIDEO_DEVICE>Périphérique vidéo USB</VIDEO_DEVICE>
Cela me fait penser à un souci bien connu des développeurs de sites Web, l'encodage, l'
UTF8.
En regardant de plus près la fonction "
_FileWriteToLine" du fichier File.au3 on peut voir un :
Or
$FO_OVERWRITE correspond à la valeur 2 et ce mode équivaut à un "
2 = Write mode (erase previous contents)".
Essayer de faire des tests en modifiant ce mode.
► Afficher le texte
Code : Tout sélectionner
32 = Use Unicode UTF16 Little Endian reading and writing mode. Reading does not override existing BOM.
64 = Use Unicode UTF16 Big Endian reading and writing mode. Reading does not override existing BOM.
128 = Use Unicode UTF8 (with BOM) reading and writing mode. Reading does not override existing BOM.
256 = Use Unicode UTF8 (without BOM) reading and writing mode.
16384 = When opening for reading and no BOM is present, use full file UTF8 detection. If this is not used then only the initial part of the file is checked for UTF8.
Sinon, postez le fichier "
C:\Videomotion\Preferences.xml", pour y faire des simulations.
Bonne journée.
Re: [..] Fonction _FileWriteToLine problème d'encodage
Posté : ven. 25 févr. 2011 10:37
par corrs78
Merci pour votre aide...
j'ai voulu commencer par le plus facile, la solution de FernandG,
mais le problème persiste. (j'ai mis la valeur 256)
curieusement, sur windows 7, j'ai remarqué que je n'avais pas ce problème de réencodage. (seulement sur win XP).
Re: [..] Fonction _FileWriteToLine problème d'encodage
Posté : ven. 25 févr. 2011 12:31
par FernandG
Bonjour,
Merci pour le fichier.
Après vérification, il est bien au format UTF8.
Très rapidement, en reprennant la fonction du fichier
Files.au3 pour l'intégrer dans un fichier "
au3" de test, cela fonctionne sous un environnement
Windows XP.
► Afficher le texte
Code : Tout sélectionner
_MyFileWriteToLine(@ScriptDir & "\Preferences.xml", 3, "ma nouvelle ligne", 1)
Exit
Func _MyFileWriteToLine($sFile, $iLine, $sText, $fOverWrite = 0)
If $iLine <= 0 Then Return SetError(4, 0, 0)
If Not IsString($sText) Then
$sText = String($sText)
If $sText = "" Then Return SetError(6, 0, 0)
EndIf
If $fOverWrite <> 0 And $fOverWrite <> 1 Then Return SetError(5, 0, 0)
If Not FileExists($sFile) Then Return SetError(2, 0, 0)
Local $sRead_File = FileRead($sFile)
Local $aSplit_File = StringSplit(StringStripCR($sRead_File), @LF)
If UBound($aSplit_File) < $iLine Then Return SetError(1, 0, 0)
Local $hFile = [color=#BF0000][b]FileOpen($sFile, 2 + 256)[/b][/color] If $hFile = -1 Then Return SetError(3, 0, 0)
$sRead_File = ""
For $i = 1 To $aSplit_File[0]
If $i = $iLine Then
If $fOverWrite = 1 Then
If $sText <> '' Then $sRead_File &= $sText & @CRLF
Else
$sRead_File &= $sText & @CRLF & $aSplit_File[$i] & @CRLF
EndIf
ElseIf $i < $aSplit_File[0] Then
$sRead_File &= $aSplit_File[$i] & @CRLF
ElseIf $i = $aSplit_File[0] Then
$sRead_File &= $aSplit_File[$i]
EndIf
Next
FileWrite($hFile, $sRead_File)
FileClose($hFile)
Return 1
EndFunc
Bonne journée.
Re: [..] Fonction _FileWriteToLine problème d'encodage
Posté : ven. 25 févr. 2011 12:36
par GaRydelaMer
Bonjour
j'étais parti sur le même chemin que toi, mais je voulais pas modifier une fonction déjà livré car elle gère pas l'encodage ou l'handler du ficher ce qui serais mieux.
C'est pour ca que j'ai proposé une autre approche, ce qui permet aussi de progressé.
► Afficher le texte
Code : Tout sélectionner
_XML_WriteValue("Preference.xml", "//VIDEO_DEVICE", "Périphérique Vidéo USB")
Func _XML_WriteValue($URL, $XPath = "", $Value = "")
Local $xmlDoc = ObjCreate("Msxml2.DOMDocument.6.0")
If Not IsObj($xmlDoc) Then
ConsoleWrite("Erreur N°1 Impossible de créer un objet MSXML." & @CRLF)
$xmlDoc = 0
Return SetError(1)
EndIf
$xmlDoc.async = False
$xmlDoc.preserveWhiteSpace = True
$xmlDoc.load($URL)
If $xmlDoc.ParseError.ErrorCode <> 0 Then
ConsoleWrite("Erreur N°2 Load: URL: """ & $URL & """." & @CRLF & StringStripWS($xmlDoc.ParseError.Reason, 7) & @CRLF)
$xmlDoc = 0
Return SetError(2)
EndIf
If $XPath = "" Then
ConsoleWrite("Erreur N°3 SelectSingleNode: XPath vide." & @CRLF)
$xmlDoc = 0
Return SetError(3)
EndIf
$xmlDoc.setProperty("SelectionLanguage", "XPath")
Local $Node = $xmlDoc.selectSingleNode($XPath)
If Not IsObj($Node) Then
ConsoleWrite("Erreur N°4 Aucun Noeud atteint aucune modification: XPath """ & $XPath & """." & @CRLF & StringStripWS($xmlDoc.ParseError.Reason, 7) & @CRLF)
$xmlDoc = 0
Exit SetError(4)
Else
$Node.text = $Value
$xmlDoc.Save($xmlDoc.url)
EndIf
Return True
EndFunc
Qui au final est plus court.
PS: Je vous prépare pour bientôt une UDF pour les fichiers XML.
Re: [..] Fonction _FileWriteToLine problème d'encodage
Posté : ven. 25 févr. 2011 12:42
par FernandG
GaRydelaMer a écrit :mais je voulais pas modifier une fonction déjà livré
@corrs78 Je confirme les dires de
GaRydelaMer ne pas modifier la fonction d'origine, le fichier
Files.au3. Par contre on peut la modifier et l'intégrer dans son propre fichier
au3, d'où le changement de nom en
_MyFileWriteToLine.
GaRydelaMer a écrit :PS: Je vous prépare pour bientôt une UDF pour les fichiers XML.
Ah ... je suis preneur

Re: [..] Fonction _FileWriteToLine problème d'encodage
Posté : ven. 25 févr. 2011 16:21
par corrs78
Merci à vous ça fonctionne à merveille !
Re: [..] Fonction _FileWriteToLine problème d'encodage
Posté : ven. 25 févr. 2011 16:58
par TommyDDR
Et quand ça fonctionne, on pense au petit [R]
