IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Traiter un fichier XML (je m'y perds avec les interfaces)


Sujet :

Langage Delphi

  1. #1
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 036
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut Traiter un fichier XML (je m'y perds avec les interfaces)
    Bonsoir,

    cela fait quelques heures que je tourne en rond sur un truc certainement tout bête !

    j'ai un fichier XML
    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    <?xml version="1.0" encoding="UTF-8"?>
    <gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
    	<gesmes:subject>Reference rates</gesmes:subject>
    	<gesmes:Sender>
    		<gesmes:name>European Central Bank</gesmes:name>
    	</gesmes:Sender>
    	<Cube>
    		<Cube time='2017-03-28'>
    			<Cube currency='USD' rate='1.0859'/>
    			<Cube currency='JPY' rate='119.84'/>
    			<Cube currency='BGN' rate='1.9558'/>
    			<Cube currency='CZK' rate='27.021'/>
    			<Cube currency='DKK' rate='7.4406'/>
    			<Cube currency='GBP' rate='0.86455'/>
    			<Cube currency='HUF' rate='309.19'/>
    			<Cube currency='PLN' rate='4.2470'/>
    			<Cube currency='RON' rate='4.5529'/>
    			<Cube currency='SEK' rate='9.5318'/>
    			<Cube currency='CHF' rate='1.0693'/>
    			<Cube currency='NOK' rate='9.2380'/>
    			<Cube currency='HRK' rate='7.4325'/>
    			<Cube currency='RUB' rate='61.8842'/>
    			<Cube currency='TRY' rate='3.9353'/>
    			<Cube currency='AUD' rate='1.4281'/>
    			<Cube currency='BRL' rate='3.3947'/>
    			<Cube currency='CAD' rate='1.4546'/>
    			<Cube currency='CNY' rate='7.4767'/>
    			<Cube currency='HKD' rate='8.4346'/>
    			<Cube currency='IDR' rate='14441.86'/>
    			<Cube currency='ILS' rate='3.9250'/>
    			<Cube currency='INR' rate='70.6435'/>
    			<Cube currency='KRW' rate='1209.11'/>
    			<Cube currency='MXN' rate='20.4927'/>
    			<Cube currency='MYR' rate='4.7951'/>
    			<Cube currency='NZD' rate='1.5454'/>
    			<Cube currency='PHP' rate='54.487'/>
    			<Cube currency='SGD' rate='1.5137'/>
    			<Cube currency='THB' rate='37.371'/>
    			<Cube currency='ZAR' rate='14.0518'/>
    		</Cube>
    	</Cube>
    </gesmes:Envelope>
    j'ai donc poser sur ma forme un XMLDocument et généré les classes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
     
    {****************************************************************************}
    {                                                                            }
    {                           Liaison de données XML                           }
    {                                                                            }
    {         Généré le : 29/03/2017 16:27:22                                    }
    {       Généré depuis : F:\Livebindings\Programmes\VCL\eurofxref-daily.xml   }
    {                                                                            }
    {****************************************************************************}
     
    unit eurofxrefdaily;
     
    interface
     
    uses xmldom, XMLDoc, XMLIntf;
     
    type
     
    { Décl. Forward }
     
      IXMLEnvelopeType = interface;
      IXMLSenderType = interface;
      IXMLCours = interface;
      IXMLDevise = interface;
     
    { IXMLEnvelopeType }
     
      IXMLEnvelopeType = interface(IXMLNode)
        ['{37B402E6-03EA-4A7D-8AD5-B135189B20DA}']
        { Accesseurs de propriétés }
        function Get_Xmlns: UnicodeString;
        function Get_Subject: UnicodeString;
        function Get_Sender: IXMLSenderType;
        function Get_Cube: IXMLCours;
        procedure Set_Xmlns(Value: UnicodeString);
        procedure Set_Subject(Value: UnicodeString);
        { Méthodes & propriétés }
        property Xmlns: UnicodeString read Get_Xmlns write Set_Xmlns;
        property Subject: UnicodeString read Get_Subject write Set_Subject;
        property Sender: IXMLSenderType read Get_Sender;
        property Cube: IXMLCours read Get_Cube;
      end;
     
    { IXMLSenderType }
     
      IXMLSenderType = interface(IXMLNode)
        ['{CCC891D6-864D-4844-A3C6-D0CF1B85AE90}']
        { Accesseurs de propriétés }
        function Get_Name: UnicodeString;
        procedure Set_Name(Value: UnicodeString);
        { Méthodes & propriétés }
        property Name: UnicodeString read Get_Name write Set_Name;
      end;
     
    { IXMLCours }
     
      IXMLCours = interface(IXMLNodeCollection)
        ['{66C5B4C2-DA5A-4A6F-91ED-A6842868E3F8}']
        { Accesseurs de propriétés }
        function Get_Time: UnicodeString;
        function Get_Cube(Index: Integer): IXMLDevise;
        procedure Set_Time(Value: UnicodeString);
        { Méthodes & propriétés }
        function Add: IXMLDevise;
        function Insert(const Index: Integer): IXMLDevise;
        property Time: UnicodeString read Get_Time write Set_Time;
        property Cube[Index: Integer]: IXMLDevise read Get_Cube; default;
      end;
     
    { IXMLDevise }
     
      IXMLDevise = interface(IXMLNode)
        ['{81A3ABF1-1B68-40AE-8971-8CFCF7F59095}']
        { Accesseurs de propriétés }
        function Get_Currency: UnicodeString;
        function Get_Rate: UnicodeString;
        procedure Set_Currency(Value: UnicodeString);
        procedure Set_Rate(Value: UnicodeString);
        { Méthodes & propriétés }
        property Currency: UnicodeString read Get_Currency write Set_Currency;
        property Rate: UnicodeString read Get_Rate write Set_Rate;
      end;
     
    { Décl. Forward }
     
      TXMLEnvelopeType = class;
      TXMLSenderType = class;
      TXMLCours = class;
      TXMLDevise = class;
     
    { TXMLEnvelopeType }
     
      TXMLEnvelopeType = class(TXMLNode, IXMLEnvelopeType)
      protected
        { IXMLEnvelopeType }
        function Get_Xmlns: UnicodeString;
        function Get_Subject: UnicodeString;
        function Get_Sender: IXMLSenderType;
        function Get_Cube: IXMLCours;
        procedure Set_Xmlns(Value: UnicodeString);
        procedure Set_Subject(Value: UnicodeString);
      public
        procedure AfterConstruction; override;
      end;
     
    { TXMLSenderType }
     
      TXMLSenderType = class(TXMLNode, IXMLSenderType)
      protected
        { IXMLSenderType }
        function Get_Name: UnicodeString;
        procedure Set_Name(Value: UnicodeString);
      end;
     
    { TXMLCours }
     
      TXMLCours = class(TXMLNodeCollection, IXMLCours)
      protected
        { IXMLCours }
        function Get_Time: UnicodeString;
        function Get_Cube(Index: Integer): IXMLDevise;
        procedure Set_Time(Value: UnicodeString);
        function Add: IXMLDevise;
        function Insert(const Index: Integer): IXMLDevise;
      public
        procedure AfterConstruction; override;
      end;
     
    { TXMLDevise }
     
      TXMLDevise = class(TXMLNode, IXMLDevise)
      protected
        { IXMLDevise }
        function Get_Currency: UnicodeString;
        function Get_Rate: UnicodeString;
        procedure Set_Currency(Value: UnicodeString);
        procedure Set_Rate(Value: UnicodeString);
      end;
     
    { Fonctions globales }
     
    function GetEnvelope(Doc: IXMLDocument): IXMLEnvelopeType;
    function LoadEnvelope(const FileName: string): IXMLEnvelopeType;
    function NewEnvelope: IXMLEnvelopeType;
     
    const
      TargetNamespace = 'http://www.gesmes.org/xml/2002-08-01';
     
    implementation
     
    { Fonctions globales }
     
    function GetEnvelope(Doc: IXMLDocument): IXMLEnvelopeType;
    begin
      Result := Doc.GetDocBinding('Envelope', TXMLEnvelopeType, TargetNamespace) as IXMLEnvelopeType;
    end;
     
    function LoadEnvelope(const FileName: string): IXMLEnvelopeType;
    begin
      Result := LoadXMLDocument(FileName).GetDocBinding('Envelope', TXMLEnvelopeType, TargetNamespace) as IXMLEnvelopeType;
    end;
     
    function NewEnvelope: IXMLEnvelopeType;
    begin
      Result := NewXMLDocument.GetDocBinding('Envelope', TXMLEnvelopeType, TargetNamespace) as IXMLEnvelopeType;
    end;
     
    { TXMLEnvelopeType }
     
    procedure TXMLEnvelopeType.AfterConstruction;
    begin
      RegisterChildNode('Sender', TXMLSenderType);
      RegisterChildNode('Cube', TXMLCours);
      inherited;
    end;
     
    function TXMLEnvelopeType.Get_Xmlns: UnicodeString;
    begin
      Result := AttributeNodes['xmlns'].Text;
    end;
     
    procedure TXMLEnvelopeType.Set_Xmlns(Value: UnicodeString);
    begin
      SetAttribute('xmlns', Value);
    end;
     
    function TXMLEnvelopeType.Get_Subject: UnicodeString;
    begin
      Result := ChildNodes['subject'].Text;
    end;
     
    procedure TXMLEnvelopeType.Set_Subject(Value: UnicodeString);
    begin
      ChildNodes['subject'].NodeValue := Value;
    end;
     
    function TXMLEnvelopeType.Get_Sender: IXMLSenderType;
    begin
      Result := ChildNodes['Sender'] as IXMLSenderType;
    end;
     
    function TXMLEnvelopeType.Get_Cube: IXMLCours;
    begin
      Result := ChildNodes['Cube'] as IXMLCours;
    end;
     
    { TXMLSenderType }
     
    function TXMLSenderType.Get_Name: UnicodeString;
    begin
      Result := ChildNodes['name'].Text;
    end;
     
    procedure TXMLSenderType.Set_Name(Value: UnicodeString);
    begin
      ChildNodes['name'].NodeValue := Value;
    end;
     
    { TXMLCours }
     
    procedure TXMLCours.AfterConstruction;
    begin
      RegisterChildNode('Cube', TXMLDevise);
      ItemTag := 'Cube';
      ItemInterface := IXMLDevise;
      inherited;
    end;
     
    function TXMLCours.Get_Time: UnicodeString;
    begin
      Result := AttributeNodes['time'].Text;
    end;
     
    procedure TXMLCours.Set_Time(Value: UnicodeString);
    begin
      SetAttribute('time', Value);
    end;
     
    function TXMLCours.Get_Cube(Index: Integer): IXMLDevise;
    begin
      Result := List[Index] as IXMLDevise;
    end;
     
    function TXMLCours.Add: IXMLDevise;
    begin
      Result := AddItem(-1) as IXMLDevise;
    end;
     
    function TXMLCours.Insert(const Index: Integer): IXMLDevise;
    begin
      Result := AddItem(Index) as IXMLDevise;
    end;
     
    { TXMLDevise }
     
    function TXMLDevise.Get_Currency: UnicodeString;
    begin
      Result := AttributeNodes['currency'].Text;
    end;
     
    procedure TXMLDevise.Set_Currency(Value: UnicodeString);
    begin
      SetAttribute('currency', Value);
    end;
     
    function TXMLDevise.Get_Rate: UnicodeString;
    begin
      Result := AttributeNodes['rate'].Text;
    end;
     
    procedure TXMLDevise.Set_Rate(Value: UnicodeString);
    begin
      SetAttribute('rate', Value);
    end;
     
    end.
    maintenant, comment y accéder !
    soit ce bout de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function getentete : String;
    var Envelope : IXMLEnvelopeType;
    begin
    Envelope:=GetEnvelope(XmLDocument1);
    result:=envelope.Sender.Name + Envelope.Cube.Time; 
    end;
    j'obtiens bien tout ce qui concerne le sender mais, impossible d'obtenir quoique ce soit d'autre (la partie qui m'intéresse vraiment, c'est à dire la date et un ou plusieurs cours.
    Je sens que je rate quelque chose mais j'arrive pas à mettre le doigt dessus, les interfaces étant pour moi, quelque chose de très nouveau (et donc encore trouble)
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 452
    Points : 24 863
    Points
    24 863
    Par défaut
    Cela devrait te plaire, j'ai refais la lecture de ce XML à ma façon dans un projet
    l'ancienne fonction parsait un HTML à coup de Pos

    Voici le code, si il manque des trucs, tu me le dit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    //------------------------------------------------------------------------------
    function TFM_MAJCOURSOR.TrouverPariteEuroDollar(const ADateCours:TDate; out APariteEuroDollar: Currency): Boolean;
     
      function SelectManualNode(AXMLDocIntf: IXMLDocument; const ALevel2Criterion, ALevel3Criterion: string): IDOMNode;
      const
        LEVEL_0 = 'Envelope';
        LEVEL_1 = 2; // Par son nom Cube, il semble confondre le Noeuds et sous-Noeuds
        LEVEL_2 = 'Cube';
        LEVEL_2_CRITERION = 'time';
        LEVEL_3 = 'Cube';
        LEVEL_3_CRITERION = 'currency';
      var
        NodeL0, NodeL1, NodeL2, NodeL3: IXMLNode;
      begin
        // Structure codé en dur !
        NodeL0 := AXMLDocIntf.Node.ChildNodes.Nodes[LEVEL_0];
        NodeL1 := NodeL0.ChildNodes.Nodes[LEVEL_1];
        NodeL2 := NodeL1.ChildNodes.Nodes[LEVEL_2];
     
        if NodeL2.Attributes[LEVEL_2_CRITERION] = ALevel2Criterion then
        begin
          NodeL3 := NodeL2.ChildNodes.Nodes[LEVEL_3];
          if NodeL3.Attributes[LEVEL_3_CRITERION] = ALevel3Criterion then
            Result := NodeL3.DOMNode;
        end;
      end;
     
    const
      URL_BCE_WS_XML = 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml';
      // Pour gérer le namespace et éviter l'erreur "Erreur d'exécution '-2147467259(80004005) ': une référence pour le préfixe d'espace de noms non déclaré: '< Préfixe d'espace de Noms >' "
      // la fonction local-name() permet de trouver le noeud Envelope même si il est exprimé avec son namespace gesmes sous la forme gesmes:Envelope
      // la constante XPATH_PARITY_FMT est une variante complexe mais fonctionnelle car la forme simple ne fonctionne pas '/Envelope/Cube/Cube[@time="%s"]/Cube[@currency="%s"]';
      XPATH_PARITY_FMT = '/*[local-name()="Envelope"]/*[local-name()="Cube"]/*[local-name()="Cube" and @time="%s"]/*[local-name()="Cube" and @currency="%s"]';
      USDOLLAR = 'USD';
      CUBE_FMT = 'YYYY-MM-DD';
      PARITY_ATTRIBUTE_NAME = 'rate';
      XML_DECIMAL_SEPARATOR = '.';
    var
      HTTPGetter: TIdHTTP;
      HTTPXMLStream: TMemoryStream;
      XMLDocIntf: IXMLDocument;
      DomNodeSelectIntf : IDomNodeSelect;
      XPath: string;
      DOMNodeCubeIntf, DOMNodeParityIntf: IDOMNode;
      XMLFormatSettings: TFormatSettings;
      BatchMsg, BatchMsgXML: string;
    begin
      Result := False;
      APariteEuroDollar := 0;
     
      // Utilisation d'un WebService renvoyé un fichier XML
      HTTPGetter := TIdHTTP.Create();
      try
        HTTPXMLStream := TMemoryStream.Create();
        try
          try
            HTTPGetter.Get(URL_BCE_WS_XML, HTTPXMLStream);
     
            XMLDocIntf := TXMLDocument.Create(nil);
            try
              XMLDocIntf.LoadFromStream(HTTPXMLStream);
              XMLDocIntf.Active := True;
     
              if Assigned(XMLDocIntf.DOMDocument) and Supports(XMLDocIntf.DOMDocument, IDomNodeSelect, DomNodeSelectIntf) then
              begin
                try
                  // Récupère le taux de change fixé la veille, normalement c'est AVANT midi
                  // La BCE semble changer son cours vers 14h !
                  XPath := Format(XPATH_PARITY_FMT, [FormatDateTime(CUBE_FMT, ADateCours-1), USDOLLAR]);
                  DOMNodeCubeIntf := DomNodeSelectIntf.selectNode(XPath);
                  // Si on n'a pas le cours de la veille, on a peut-être celui du jour !
                  if not Assigned(DOMNodeCubeIntf) then
                  begin
                    XPath := Format(XPATH_PARITY_FMT, [FormatDateTime(CUBE_FMT, ADateCours), USDOLLAR]);
                    DOMNodeCubeIntf := DomNodeSelectIntf.selectNode(XPath);
                  end
                except
                  on E: Exception do
                  begin
    AddToLogFile(ChangeFileExt(ParamStr(0), '.log') , 'Lecture manuelle du XML car selectNode inopérant');
                    DOMNodeCubeIntf := SelectManualNode(XMLDocIntf, FormatDateTime(CUBE_FMT, ADateCours-1), USDOLLAR);
                    if not Assigned(DOMNodeCubeIntf) then
                      DOMNodeCubeIntf := SelectManualNode(XMLDocIntf, FormatDateTime(CUBE_FMT, ADateCours), USDOLLAR);
    //                if not Assigned(DOMNodeCubeIntf) then
    //                  raise;
                  end;
                end;
     
                if Assigned(DOMNodeCubeIntf) then
                begin
                  DOMNodeParityIntf := DOMNodeCubeIntf.attributes.getNamedItem(PARITY_ATTRIBUTE_NAME);
                  if Assigned(DOMNodeParityIntf) then
                  begin
                    // D'abord, on tente le format local de séparateur décimal (cela devrait être celui de la France donc virgule)
                    Result := TryStrToCurr(DOMNodeParityIntf.nodeValue, APariteEuroDollar);
                    // Si le format local ne passe pas, on utilise celui observé durant le développement en mars 2015, cad le point !
                    if not Result and (FormatSettings.DecimalSeparator <> XML_DECIMAL_SEPARATOR) then
                    begin
                      XMLFormatSettings := TFormatSettings.Create();
                      XMLFormatSettings.DecimalSeparator := XML_DECIMAL_SEPARATOR;
                      Result := TryStrToCurr(DOMNodeParityIntf.nodeValue, APariteEuroDollar, XMLFormatSettings);
                    end;
                  end
                  else
                    BatchMsg := 'ERREUR : Document XML incomplet - valeur de parité non trouvée !';
                end
     
                // Pas de cours trouvé pour la date
                else
                begin
                  AddToLogFile(ChangeFileExt(ParamStr(0), '.log') , Format('ERREUR : Document XML pas à jour - parité dollar non trouvée au %s !', [FormatDateTime(CUBE_FMT, ADateCours-1)]));
                  Exit;
                end;
              end
              else
                BatchMsg := 'ERREUR : Document XML invalide';
     
              // Une alerte uniquement en mode Batch
              if not Result and FModeSilent then
              begin
                XMLDocIntf.Options := [doNodeAutoIndent];
                XMLDocIntf.SaveToXML(BatchMsgXML);
              end;
     
            finally
              XMLDocIntf := nil;
            end;
          except
            on E: Exception do
            begin
              BatchMsg := Format('Exception %s durant TrouverPariteEuroDollar : "%s"', [E.ClassName(), E.Message]);
              OutputDebugString(PChar(BatchMsg));
              BatchAlert(BatchMsg, BatchMsgXML);
     
              Exit();
            end;
          end;
     
        finally
          HTTPXMLStream.Free();
        end;
      finally
        HTTPGetter.Free();
      end;
     
      if not Result then
        BatchAlert(BatchMsg, BatchMsgXML);
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 036
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    Oui, ça me plait toujours de lire une méthode à la ShaiLeTroll , je pourrais en proposer d'autres plus "vieux de la vieille" ou même, peut-être, à coup d'expressions régulières

    Mais, ne m'en veut pas, ce n'est pas vraiment l'objet de mon post. Pour mieux m'expliquer: j'ai fait une approche de débutant sur les fichiers XML avec les outils proposés par RAD Studio (Tokyo).

    Donc, pose d'un TXMLDocument et chargement d'un fichier, puis génération des méthodes via l' Expert de liaison de données XML.
    Toujours, "débutant", je me suis dit, mode [poil dans la main] : "chouette du code tout fait",
    "Vieux routard" mais toujours même mode : "Hum! les interfaces, ça tombe bien, je voulais voir comment cela fonctionne, beaucoup de code, mais que du généré donc je ne devrait pas avoir de soucis"

    Ce que je loupe c'est l'accès à la section <Code> qui me semble pourtant déclarée et accessible.
    Ce que je n'ai pas fait, c'est voir si une autre version de Delphi me fournirait le même code (cela fait un bail que je n'ai pas traité de XML et encore, pas sous cette forme, je me demande quand cet expert de liaison est apparu) donc je suis rouillé.
    [Edit] avec XE4, l'expert est moins bon (par défaut il me propose de récupéré des integers au lieu de strings, avec un peu de manips, on récupère des strings, mais, même problème !
    avec D2010 ou D7 "mais bon sang où est cet expert ?!" j'étais pourtant sûr d'en avoir utilisé un du moins avec D2010 !

    Ce que je ne voulais pas faire, du moins essayer de ne pas faire, c'est me balader dans les nœuds avec du code non généré

    L'objectif "final" , c'est un programme de démonstration inclus dans un tutoriel niveau débutant, concernant les Livebindings (une suite), ce truc est donc "marginal" mais énervant
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 452
    Points : 24 863
    Points
    24 863
    Par défaut
    Je te confirme qu'il existait en D7 mais peut-être en version Entreprise, je me demande si j'avais pas même généré les interfaces avec un D6 Ent pour l'utiliser en D7 Pro

    Sinon, tu veux la méthode pour débutant, oui mon code ne l'est pas
    Entre le XPATH qui ne fonctionne pas sur toutes les machines (la mienne pas de soucis mais pas sur le poste de mon collègue ou sur l'un des serveurs)
    Donc j'ai fait ma propre fonction d'extraction à l'arrache

    sinon, ceci compile mais ne fonctionne pas car il cherche "gesmes:Cube" au lieu de "Cube"
    C'est pour cela que dans mon XPATH, j'utilisais "*[local-name()="Cube"]"

    Je pense qu'il manque un niveau de Cube dans les interfaces générées

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    procedure TZooThomVCLMainForm.Memo2DblClick(Sender: TObject);
    var
      Envelope: IXMLEnvelopeType;
      Msg: string;
      I: Integer;
    begin
      XMLDocument1.XML := Memo2.Lines;
      XMLDocument1.Active := True;
     
      Envelope := GetEnvelope(XMLDocument1);
      Msg := Envelope.Subject +  ' - ' + Envelope.Sender.Name + ' - ' + Envelope.Cube.Time + sLineBreak;
      for I := 0 to Envelope.Cube.Count - 1 do
        Msg := Msg + Format('%s : %s', [Envelope.Cube.Cube[I].Currency, Envelope.Cube.Cube[I].Rate]);
      ShowMessage(Msg);
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 452
    Points : 24 863
    Points
    24 863
    Par défaut
    J'ai ajouté le niveau manquant
    J'ai corrigé la fonction récupérant le premier du Cube

    lecture

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    procedure TZooThomVCLMainForm.Memo2DblClick(Sender: TObject);
    var
      Envelope: IXMLEnvelopeType;
      Msg: string;
      I: Integer;
    begin
      XMLDocument1.XML := Memo2.Lines;
      XMLDocument1.Active := True;
     
      Envelope := GetEnvelope(XMLDocument1);
      Msg := Envelope.Subject +  ' - ' + Envelope.Sender.Name + ' - ' + Envelope.Cube.Cube.Time + sLineBreak;
      for I := 0 to Envelope.Cube.Cube.Count - 1 do
        Msg := Msg + Format('- %s : %s', [Envelope.Cube.Cube.Cube[I].Currency, Envelope.Cube.Cube.Cube[I].Rate]) + sLineBreak;
      ShowMessage(Msg);
    end;
    Résultat

    [Window Title]
    Zoothomvcl

    [Content]
    Reference rates - European Central Bank - 2017-03-28
    - USD : 1.0859
    - JPY : 119.84
    - BGN : 1.9558
    - CZK : 27.021
    - DKK : 7.4406
    - GBP : 0.86455
    - HUF : 309.19
    - PLN : 4.2470
    - RON : 4.5529
    - SEK : 9.5318
    - CHF : 1.0693
    - NOK : 9.2380
    - HRK : 7.4325
    - RUB : 61.8842
    - TRY : 3.9353
    - AUD : 1.4281
    - BRL : 3.3947
    - CAD : 1.4546
    - CNY : 7.4767
    - HKD : 8.4346
    - IDR : 14441.86
    - ILS : 3.9250
    - INR : 70.6435
    - KRW : 1209.11
    - MXN : 20.4927
    - MYR : 4.7951
    - NZD : 1.5454
    - PHP : 54.487
    - SGD : 1.5137
    - THB : 37.371
    - ZAR : 14.0518
    [OK]

    Interfaces

    j'ai importé via XE2 mais j'ai modifié le fichier XML comme ceci

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	</gesmes:Sender>
    	<Cube3 k='k'>
    		<Cube time='2017-03-28'>
    cela lui a forcé la génération du niveau Cube entre Cube\Cours et Cube\Devise
    J'ai ensuite retirer les apparitions de K dans le source généré

    et j'ai changé la recherche du nœud

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function TXMLEnvelopeType.Get_Cube: IXMLCubeType;
    begin
      Result := ChildNodes['Cube'] as IXMLCubeType;
    end;
    devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    function TXMLEnvelopeType.Get_Cube: IXMLCubeType;
    var
      I: Integer;
      Node: IXMLNode;
    begin
      for I := 0 to ChildNodes.Count - 1 do
      begin
        Node := ChildNodes.Nodes[I];
        if Node.NodeName = 'Cube' then
          Exit(TXMLCubeType.Create(Node.DOMNode, Self, Self.OwnerDocument));
      end;
    end;

    voici le fichier complet
    Ce n'est plus très débutant !
    Ce xml contient un piege avec ses namespaces foireux


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
     
     
    {******************************************************************************************************}
    {                                                                                                      }
    {                                        Liaison de données XML                                        }
    {                                                                                                      }
    {******************************************************************************************************}
     
    unit eurofxrefdaily;
     
    interface
     
    uses xmldom, XMLDoc, XMLIntf;
     
    type
     
    { Décl. Forward }
     
      IXMLEnvelopeType = interface;
      IXMLSenderType = interface;
      IXMLCubeType = interface;
      IXMLCoursType = interface;
      IXMLDeviseType = interface;
     
    { IXMLEnvelopeType }
     
      IXMLEnvelopeType = interface(IXMLNode)
        ['{2CB4482F-8004-447E-BC3F-D7C62A16B0AB}']
        { Accesseurs de propriétés }
        function Get_Xmlns: UnicodeString;
        function Get_Subject: UnicodeString;
        function Get_Sender: IXMLSenderType;
        function Get_Cube: IXMLCubeType;
        procedure Set_Xmlns(Value: UnicodeString);
        procedure Set_Subject(Value: UnicodeString);
        { Méthodes & propriétés }
        property Xmlns: UnicodeString read Get_Xmlns write Set_Xmlns;
        property Subject: UnicodeString read Get_Subject write Set_Subject;
        property Sender: IXMLSenderType read Get_Sender;
        property Cube: IXMLCubeType read Get_Cube;
      end;
     
    { IXMLSenderType }
     
      IXMLSenderType = interface(IXMLNode)
        ['{BDF7614E-C418-460E-8BB7-301F16AE6573}']
        { Accesseurs de propriétés }
        function Get_Name: UnicodeString;
        procedure Set_Name(Value: UnicodeString);
        { Méthodes & propriétés }
        property Name: UnicodeString read Get_Name write Set_Name;
      end;
     
    { IXMLCubeType }
     
      IXMLCubeType = interface(IXMLNode)
        ['{C9C000F1-C5A2-4CE6-B27C-F867BCBABC96}']
        { Accesseurs de propriétés }
        function Get_Cube: IXMLCoursType;
        { Méthodes & propriétés }
        property Cube: IXMLCoursType read Get_Cube;
      end;
     
    { IXMLCoursType }
     
      IXMLCoursType = interface(IXMLNodeCollection)
        ['{27400E9B-9F77-4668-93D9-8F31B1A2D1A0}']
        { Accesseurs de propriétés }
        function Get_Time: UnicodeString;
        function Get_Cube(Index: Integer): IXMLDeviseType;
        procedure Set_Time(Value: UnicodeString);
        { Méthodes & propriétés }
        function Add: IXMLDeviseType;
        function Insert(const Index: Integer): IXMLDeviseType;
        property Time: UnicodeString read Get_Time write Set_Time;
        property Cube[Index: Integer]: IXMLDeviseType read Get_Cube; default;
      end;
     
    { IXMLDeviseType }
     
      IXMLDeviseType = interface(IXMLNode)
        ['{2548C220-1A58-4A82-9CEE-5DAF3BA6D01D}']
        { Accesseurs de propriétés }
        function Get_Currency: UnicodeString;
        function Get_Rate: UnicodeString;
        procedure Set_Currency(Value: UnicodeString);
        procedure Set_Rate(Value: UnicodeString);
        { Méthodes & propriétés }
        property Currency: UnicodeString read Get_Currency write Set_Currency;
        property Rate: UnicodeString read Get_Rate write Set_Rate;
      end;
     
    { Décl. Forward }
     
      TXMLEnvelopeType = class;
      TXMLSenderType = class;
      TXMLCubeType = class;
      TXMLCoursType = class;
      TXMLDeviseType = class;
     
    { TXMLEnvelopeType }
     
      TXMLEnvelopeType = class(TXMLNode, IXMLEnvelopeType)
      protected
        { IXMLEnvelopeType }
        function Get_Xmlns: UnicodeString;
        function Get_Subject: UnicodeString;
        function Get_Sender: IXMLSenderType;
        function Get_Cube: IXMLCubeType;
        procedure Set_Xmlns(Value: UnicodeString);
        procedure Set_Subject(Value: UnicodeString);
      public
        procedure AfterConstruction; override;
      end;
     
    { TXMLSenderType }
     
      TXMLSenderType = class(TXMLNode, IXMLSenderType)
      protected
        { IXMLSenderType }
        function Get_Name: UnicodeString;
        procedure Set_Name(Value: UnicodeString);
      end;
     
    { TXMLCubeType }
     
      TXMLCubeType = class(TXMLNode, IXMLCubeType)
      protected
        { IXMLCubeType }
        function Get_Cube: IXMLCoursType;
      public
        procedure AfterConstruction; override;
      end;
     
    { TXMLCoursType }
     
      TXMLCoursType = class(TXMLNodeCollection, IXMLCoursType)
      protected
        { IXMLCoursType }
        function Get_Time: UnicodeString;
        function Get_Cube(Index: Integer): IXMLDeviseType;
        procedure Set_Time(Value: UnicodeString);
        function Add: IXMLDeviseType;
        function Insert(const Index: Integer): IXMLDeviseType;
      public
        procedure AfterConstruction; override;
      end;
     
    { TXMLDeviseType }
     
      TXMLDeviseType = class(TXMLNode, IXMLDeviseType)
      protected
        { IXMLDeviseType }
        function Get_Currency: UnicodeString;
        function Get_Rate: UnicodeString;
        procedure Set_Currency(Value: UnicodeString);
        procedure Set_Rate(Value: UnicodeString);
      end;
     
    { Fonctions globales }
     
    function GetEnvelope(Doc: IXMLDocument): IXMLEnvelopeType;
    function LoadEnvelope(const FileName: string): IXMLEnvelopeType;
    function NewEnvelope: IXMLEnvelopeType;
     
    const
      TargetNamespace = 'http://www.gesmes.org/xml/2002-08-01';
     
    implementation
     
    { Fonctions globales }
     
    function GetEnvelope(Doc: IXMLDocument): IXMLEnvelopeType;
    begin
      Result := Doc.GetDocBinding('Envelope', TXMLEnvelopeType, TargetNamespace) as IXMLEnvelopeType;
    end;
     
    function LoadEnvelope(const FileName: string): IXMLEnvelopeType;
    begin
      Result := LoadXMLDocument(FileName).GetDocBinding('Envelope', TXMLEnvelopeType, TargetNamespace) as IXMLEnvelopeType;
    end;
     
    function NewEnvelope: IXMLEnvelopeType;
    begin
      Result := NewXMLDocument.GetDocBinding('Envelope', TXMLEnvelopeType, TargetNamespace) as IXMLEnvelopeType;
    end;
     
    { TXMLEnvelopeType }
     
    procedure TXMLEnvelopeType.AfterConstruction;
    begin
      RegisterChildNode('Sender', TXMLSenderType);
      RegisterChildNode('Cube', TXMLCubeType);
      inherited;
    end;
     
    function TXMLEnvelopeType.Get_Xmlns: UnicodeString;
    begin
      Result := AttributeNodes['xmlns'].Text;
    end;
     
    procedure TXMLEnvelopeType.Set_Xmlns(Value: UnicodeString);
    begin
      SetAttribute('xmlns', Value);
    end;
     
    function TXMLEnvelopeType.Get_Subject: UnicodeString;
    begin
      Result := ChildNodes['subject'].Text;
    end;
     
    procedure TXMLEnvelopeType.Set_Subject(Value: UnicodeString);
    begin
      ChildNodes['subject'].NodeValue := Value;
    end;
     
    function TXMLEnvelopeType.Get_Sender: IXMLSenderType;
    begin
      Result := ChildNodes['Sender'] as IXMLSenderType;
    end;
     
    function TXMLEnvelopeType.Get_Cube: IXMLCubeType;
    var
      I: Integer;
      Node: IXMLNode;
    begin
      for I := 0 to ChildNodes.Count - 1 do
      begin
        Node := ChildNodes.Nodes[I];
        if Node.NodeName = 'Cube' then
          Exit(TXMLCubeType.Create(Node.DOMNode, Self, Self.OwnerDocument));
      end;
    end;
     
    { TXMLSenderType }
     
    function TXMLSenderType.Get_Name: UnicodeString;
    begin
      Result := ChildNodes['name'].Text;
    end;
     
    procedure TXMLSenderType.Set_Name(Value: UnicodeString);
    begin
      ChildNodes['name'].NodeValue := Value;
    end;
     
    { TXMLCubeType }
     
    procedure TXMLCubeType.AfterConstruction;
    begin
      RegisterChildNode('Cube', TXMLCoursType);
      inherited;
    end;
     
    function TXMLCubeType.Get_Cube: IXMLCoursType;
    begin
      Result := ChildNodes['Cube'] as IXMLCoursType;
    end;
     
    { TXMLCoursType }
     
    procedure TXMLCoursType.AfterConstruction;
    begin
      RegisterChildNode('Cube', TXMLDeviseType);
      ItemTag := 'Cube';
      ItemInterface := IXMLDeviseType;
      inherited;
    end;
     
    function TXMLCoursType.Get_Time: UnicodeString;
    begin
      Result := AttributeNodes['time'].Text;
    end;
     
    procedure TXMLCoursType.Set_Time(Value: UnicodeString);
    begin
      SetAttribute('time', Value);
    end;
     
    function TXMLCoursType.Get_Cube(Index: Integer): IXMLDeviseType;
    begin
      Result := List[Index] as IXMLDeviseType;
    end;
     
    function TXMLCoursType.Add: IXMLDeviseType;
    begin
      Result := AddItem(-1) as IXMLDeviseType;
    end;
     
    function TXMLCoursType.Insert(const Index: Integer): IXMLDeviseType;
    begin
      Result := AddItem(Index) as IXMLDeviseType;
    end;
     
    { TXMLDeviseType }
     
    function TXMLDeviseType.Get_Currency: UnicodeString;
    begin
      Result := AttributeNodes['currency'].Text;
    end;
     
    procedure TXMLDeviseType.Set_Currency(Value: UnicodeString);
    begin
      SetAttribute('currency', Value);
    end;
     
    function TXMLDeviseType.Get_Rate: UnicodeString;
    begin
      Result := AttributeNodes['rate'].Text;
    end;
     
    procedure TXMLDeviseType.Set_Rate(Value: UnicodeString);
    begin
      SetAttribute('rate', Value);
    end;
     
    end.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  6. #6
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 036
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Bonjour,
    Citation Envoyé par ShaiLeTroll Voir le message
    Ce n'est plus très débutant !
    Ce xml contient un piège avec ses namespaces foireux
    je me doutais bien qu'il y avait anguille sous roche ! Effectivement, trop de manipulations,(bien que faisable, j'entends par là via programmation) sont nécessaires pour obtenir un fichier XML exploitable. Cette histoire de gesmes: étrange tu es le pour avoir détecter ça !

    Traiter ce XML n'était donc pas une bonne piste pour une explication vers débutant
    En résumé :
    1. soit je trouve un XML exploitable d'un autre site
    2. soit je récupère non pas le XML mais le ZIP contenant le CSV (là encore le format est un peu chiant)
    3. soit je fait un traitement différent



    Comme je suis parti de ce XML, et que je pense que celui-ci sera dispo encore pendant des années (on croise les doigts), j'opte pour la solution 3.
    Comme, quand même, je ne voulais pas la faire "à la vieux de la vieille" à coup de pos, d'itérations etc.... j'ai quand même utilisé ma "marotte" : les expressions régulières (du coup cela fait plutôt débutant avancé mais tant pis)
    mon explication devient alors :
    1. Récupération du fichier XML (tant qu'à faire avec un Stream)
    2. traitement pour isoler la partie "cube" c'est à dire la date et les différents cours
    3. utilisation d'une expression régulière pour traiter cette partie
      • obtention de la date
      • chargement d'une TStringlist avec des paires devise,cours (j'aurais pu choisir une liste d'objet mais ....)


    je laisse quand même ce post ouvert pour l'instant, au cas où
    • un des lecteurs peut m'indiquer un lien vers un XML exploitable
    • un des lecteurs peut me fournir une indication d'exploitation du zip (extraction dans un stream par exemple), là j'ai un peu la flemme de chercher la caféïne du matin n'étant pas encore totalement diffusée


    En te remerciant encore ShaiLeTroll pour ton implication XML, j'ai toute la journée d'hier pensé que cela venait de moi ou du wizard

    N.B. pour plus tard, quand le sujet sera clos, vous trouverez au moins la méthode que j'ai utilisée (et peut être les autres si on me donne des pistes) dans un tutoriel que je consacrerai au Livebindings
    je n'en ai pas encore le titre, n'étant encore pas rédigé cela parait difficile de plus cette partie n'"est qu'annexe"
    toutefois, et si je m'en souviens, au moment de la publication je reviendrai mettre un lien ici (soit sur le tutoriel soit sur le programme annexé)
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 452
    Points : 24 863
    Points
    24 863
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    Effectivement, trop de manipulations,(bien que faisable, j'entends par là via programmation) sont nécessaires pour obtenir un fichier XML exploitable.
    Le fichier XML est exploitable tel quel !
    C'est le fichier Interfaces qui est un peu retord à obtenir
    Disons que c'est un candidat pour le "tutoriel avancé"

    Avec la version de eurofxrefdaily que j'ai fourni, tu lis ton fichier comme il est !
    Tu peux le tester avec la version d'aujourd'hui

    les modifications ci dessous n'ont été que pour forcer la main au parser et lui faire générer les trois niveaux de Cube
    Et faudrait tester si c'est vraiment utile

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	</gesmes:Sender>
    	<Cube3 k='k'>
    		<Cube time='2017-03-28'>

    avec le XML de ce matin

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    <?xml version="1.0" encoding="UTF-8"?>
    <gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
    	<gesmes:subject>Reference rates</gesmes:subject>
    	<gesmes:Sender>
    		<gesmes:name>European Central Bank</gesmes:name>
    	</gesmes:Sender>
    	<Cube>
    		<Cube time='2017-03-30'>
    			<Cube currency='USD' rate='1.0737'/>
    			<Cube currency='JPY' rate='119.39'/>
    			<Cube currency='BGN' rate='1.9558'/>
    			<Cube currency='CZK' rate='27.022'/>
    			<Cube currency='DKK' rate='7.4386'/>
    			<Cube currency='GBP' rate='0.86180'/>
    			<Cube currency='HUF' rate='309.35'/>
    			<Cube currency='PLN' rate='4.2233'/>
    			<Cube currency='RON' rate='4.5448'/>
    			<Cube currency='SEK' rate='9.5623'/>
    			<Cube currency='CHF' rate='1.0698'/>
    			<Cube currency='NOK' rate='9.1695'/>
    			<Cube currency='HRK' rate='7.4480'/>
    			<Cube currency='RUB' rate='60.3375'/>
    			<Cube currency='TRY' rate='3.9119'/>
    			<Cube currency='AUD' rate='1.3988'/>
    			<Cube currency='BRL' rate='3.3555'/>
    			<Cube currency='CAD' rate='1.4320'/>
    			<Cube currency='CNY' rate='7.3973'/>
    			<Cube currency='HKD' rate='8.3450'/>
    			<Cube currency='IDR' rate='14297.39'/>
    			<Cube currency='ILS' rate='3.8914'/>
    			<Cube currency='INR' rate='69.6910'/>
    			<Cube currency='KRW' rate='1199.08'/>
    			<Cube currency='MXN' rate='20.1228'/>
    			<Cube currency='MYR' rate='4.7463'/>
    			<Cube currency='NZD' rate='1.5304'/>
    			<Cube currency='PHP' rate='53.865'/>
    			<Cube currency='SGD' rate='1.4977'/>
    			<Cube currency='THB' rate='36.951'/>
    			<Cube currency='ZAR' rate='13.8165'/>
    		</Cube>
    	</Cube>
    </gesmes:Envelope>

    le code donne

    [Window Title]
    Zoothomvcl

    [Content]
    Reference rates - European Central Bank - 2017-03-30
    - USD : 1.0737
    - JPY : 119.39
    - BGN : 1.9558
    - CZK : 27.022
    - DKK : 7.4386
    - GBP : 0.86180
    - HUF : 309.35
    - PLN : 4.2233
    - RON : 4.5448
    - SEK : 9.5623
    - CHF : 1.0698
    - NOK : 9.1695
    - HRK : 7.4480
    - RUB : 60.3375
    - TRY : 3.9119
    - AUD : 1.3988
    - BRL : 3.3555
    - CAD : 1.4320
    - CNY : 7.3973
    - HKD : 8.3450
    - IDR : 14297.39
    - ILS : 3.8914
    - INR : 69.6910
    - KRW : 1199.08
    - MXN : 20.1228
    - MYR : 4.7463
    - NZD : 1.5304
    - PHP : 53.865
    - SGD : 1.4977
    - THB : 36.951
    - ZAR : 13.8165


    [OK]
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  8. #8
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 036
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Le fichier XML est exploitable tel quel !
    ...
    les modifications ci dessous n'ont été que pour forcer la main au parser et lui faire générer les trois niveaux de Cube
    Et faudrait tester si c'est vraiment utile
    j'avais compris qu'à chaque fois il fallait refaire les ajouts et non que c'était juste "pour forcer la main du parser"
    du coup, c'est plus envisageable d'utiliser l'unité faite, quoique, si les lecteurs sont comme moi qui ai horreur du "vlan je te colle l'unité" sans expliquer comment j'arrive à avoir ça, c'est moins top

    C'est le fichier Interfaces qui est un peu retord à obtenir
    Disons que c'est un candidat pour le "tutoriel avancé"
    tout à fait d'accord, mais je m'y colle pas
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

Discussions similaires

  1. conseils de modules pour traiter des fichiers XML
    Par Jasmine80 dans le forum Langage
    Réponses: 4
    Dernier message: 29/05/2015, 12h40
  2. Réponses: 4
    Dernier message: 02/09/2013, 08h51
  3. Réponses: 1
    Dernier message: 19/11/2008, 13h27
  4. Traiter un fichier xml sous vba 2003
    Par Zenerox dans le forum VBA Access
    Réponses: 2
    Dernier message: 17/06/2008, 10h34
  5. lire et traiter un fichier XML avec XMLDOM
    Par Phiss dans le forum ASP
    Réponses: 14
    Dernier message: 13/02/2007, 16h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo