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

Delphi Discussion :

[XE] Création de fichier XML


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 76
    Par défaut [XE] Création de fichier XML
    Bonjour,

    Je suis débutant dans la création de fichier xml avec delphi XE

    J'utilise le composant XMLDocument et dans mon source je créé le contenu du fichier xml au fur et à mesure

    Voici un exemple de fichier xml que je dois réaliser :

    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
     
    <?xml version="1.0"?>
    <Dossier xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://onaya.net/InterApp/Datas">
    	<InfosSource>
    		<NomSource>REHAU</NomSource>
    		<Code_Origine>TEST</Code_Origine>
    	</InfosSource>
    	<Code>TEST</Code>
    	<Libelle>LIBELLE</Libelle>
    	<Adresse_Adresse1>ADRESSE</Adresse_Adresse1>
    	<Adresse_CodePostal>99999</Adresse_CodePostal>
    	<Adresse_Ville>VILLE</Adresse_Ville>
    	<Client>
    		<Code>CODE CLIENT</Code>
    		<Type_Tiers>Client</Type_Tiers>
    		<RaisonSociale>NOM CLIENT</RaisonSociale>
    	</Client>
    	<DateCreation>2016-11-30</DateCreation>
    	<Documents>
    		<Document>
    			<DateCreation>2016-11-30</DateCreation>
    			<DateMiseAJour>2016-11-30</DateMiseAJour>
    			<ContenuDocument>
    				<Ligne_Document xsi:type="Ligne_Titre">
    					<Visible>true</Visible>
    					<Quantite>1.00</Quantite>
    					<Titre>
    						<Code>T1</Code>
    						<ContenuTitre>
    							<Ligne_Document xsi:type="Ligne_Ouvrage">
    								<Visible>true</Visible>
    								<Quantite>1</Quantite>
    								<TvaTaux>20.00</TvaTaux>
    							</Ligne_Document>
    						</ContenuTitre>
    					</Titre>
    				</Ligne_Document>
    			</ContenuDocument>
    		</Document>
    	</Documents>
    </Dossier>
    Pour réaliser cela voici mon code delphi

    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
     
    XMLDoc.Active := true;
    XMLdoc.Version := '1.0';
    XMLdoc.Encoding := 'UTF-8';
    XMLdoc.AddChild('Dossier');
    with XMLdoc.ChildNodes.Nodes['Dossier'] do
    begin
      AddChild('InfosSource');
      with ChildNodes.Nodes['InfosSource'] do
      begin
        AddChild('NomSource').Text := 'REHAU';
        AddChild('Code_Origine').Text := 'TEST';
      end;
      AddChild('Code').Text := 'TEST';
      AddChild('Libelle').Text := 'LIBELLE';
      AddChild('Adresse_Adresse1').Text := 'ADRESSE';
      AddChild('Adresse_CodePostal').Text := '99999';
      AddChild('Adresse_Ville').Text := 'VILLE';
     
      AddChild('Client');
      with ChildNodes.Nodes['Client'] do
      begin
        AddChild('Code').Text := 'CODE CLIENT';
        AddChild('Type_Tiers').Text := 'Client';
        AddChild('RaisonSociale').Text := 'NOM CLIENT';
      end;
      AddChild('DateCreation').Text := formatdatetime('yyyy-mm-dd', Now);
     
      AddChild('Documents');
     
      with XMLdoc.ChildNodes.Nodes['Dossier'].ChildNodes.Nodes['Documents'] do
      begin
        AddChild('Document');
        with XMLdoc.ChildNodes.Nodes['Dossier'].ChildNodes.Nodes['Documents'].ChildNodes.Nodes['Document'] do
        begin 
          AddChild('DateCreation').Text := formatdatetime('yyyy-mm-dd', Now);
          AddChild('DateMiseAJour').Text := formatdatetime('yyyy-mm-dd', Now) + '</DateMiseAJour>';
     
          AddChild('ContenuDocument');
          with XMLdoc.ChildNodes.Nodes['Dossier'].ChildNodes.Nodes['Documents'].ChildNodes.Nodes['Document'].ChildNodes.Nodes['ContenuDocument'] do
          begin
            AddChild('Ligne_Document');
            with XMLdoc.ChildNodes.Nodes['Dossier'].ChildNodes.Nodes['Documents'].ChildNodes.Nodes['Document'].ChildNodes.Nodes['ContenuDocument'].ChildNodes.Nodes['Ligne_Document'] do
            begin
              AddChild('Visible').Text := 'true';
              AddChild('Quantite').Text := '1.00';
    	end;
          end;
        end;
      end;
    end;
    XMLDoc.SaveToFile('.\test.xml');
    Mes questions sont les suivantes :

    - Pour la première balise (<Dossier xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://onaya.net/InterApp/Datas">) je dois indiquer des infos xmlns mais comment les renseigner dans le code ?
    - Dans le fichier XML, pour la ligne suivante " <Ligne_Document xsi:type="Ligne_Titre"> " je dois indiquer au nœud Ligne_Document l'information xsi:type="Ligne_Titre" mais je ne sais pas comment indiquer cela à ce nœud ?
    - Enfin pour ajouter des nœuds à ceux existants j'utilise cette méthode :
    with XMLdoc.ChildNodes.Nodes['Dossier'].ChildNodes.Nodes['Documents'].ChildNodes.Nodes['Document'].ChildNodes.Nodes['ContenuDocument'].ChildNodes.Nodes['Ligne_Document'] do
    L'inconvénient est que plus j'ai de noeux "père" plus la ligne va être longue est le risque d'oubli / erreur important.
    N'est il pas possible dans ce cas de me positionner directement sur le nœud "Ligne_Document" ? Si oui par quelle instruction de code ?

    En espérant avoir été clair dans mes demandes.

    merci d'avance pour votre aide

  2. #2
    Membre expérimenté Avatar de franckcl
    Homme Profil pro
    Developpeur Delphi
    Inscrit en
    Septembre 2004
    Messages
    516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Developpeur Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 516
    Par défaut
    Avec ce code (tu dois juste ajouter un uses Xml.XMLIntf):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    procedure TFormApp.Button1Click(Sender: TObject);
    var
     XMLDoc: TXMLDocument;
    begin
      XMLDoc:=TXMLDocument.create(self);
      XmlDoc.Options := [doNodeAutoIndent, doAttrNull, doAutoSave];
      XmlDoc.Active := true;
      XMLWrite(XMLDoc,'Dossier/', 'xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
      XMLWrite(XMLDoc,'Dossier/', 'xmlns', 'http://onaya.net/InterApp/Datas');
      XMLDoc.saveToFile('c:\temp\test.xml');
      XMLDoc.free;
    end;
    Tu obtiendras ceci:

    <dossier xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://onaya.net/InterApp/Datas"/>

    J'ai créé les fonctions suivantes:
    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
     
    //------------------------------------------------------------------------------------------------------------------------------
    // XMLWrite: Update the attribut to the xml document and create it if it does not exists
    // example:  XMLWrite(xml,'xml/Chambers/Chamber1/Name',Name);
    //------------------------------------------------------------------------------------------------------------------------------
    Procedure XMLWrite(XMLDoc: TXMLDocument; Path,Item, Value: String);
    Var
      S: string;
      node: IXMLNode;
      P: integer;
    Begin
      {$ifdef debug}
      if Path[length(Path)]<>'/' then ShowMessage('Erreur le chemin doit se terminer par / dans la fonction XMLWrite dans common.pas:'+Path+' and item='+item);
      if (Item='') or (Item[length(Item)]='/') or (Item[1]='/') then ShowMessage('Erreur dans la fonction XMLWrite, item non conforme: '+Item+' avec le path='+Path);
      {$endif}
      Path := lowercase(Path); // we change the path in small letters
      P := Pos('/', Path);
      S := Copy(Path, 1, P - 1);
      delete(Path, 1, P);
      node := XMLDoc.ChildNodes.FindNode(S); // Search the node
      if (node = nil) and (S<>'') then node := XMLDoc.AddChild(S); // and create it if it doesn't exist
      while (P > 0) do
      Begin
        P := Pos('/', Path);
        if (P > 0) then
        Begin
          S := Copy(Path, 1, P - 1);
          delete(Path, 1, P);
          if (node.ChildNodes.FindNode(S) <> nil)
            then node := node.ChildNodes.FindNode(S)
            else node := node.AddChild(S);
        End;
      End;
      if assigned(node) then node.Attributes[lowercase(item)] := Value; // node.Attributes[S] := Value;
    End;
     
    //------------------------------------------------------------------------------------------------------------------------------
    // XMLRead : Read a value in a xml file
    // example: CreationVersion := XMLRead(xml,'xml/version',version);
    //------------------------------------------------------------------------------------------------------------------------------
    Function XMLRead(XMLDoc: TXMLDocument; Chemin, default: String): String;
    Var
      S: string;
      node: IXMLNode;
      P: integer;
    Begin
      result := Default;
      Chemin := lowercase(Chemin); // we change the path in small letters
      P := Pos('/', Chemin);
      S := Copy(Chemin, 1, P - 1);
      delete(Chemin, 1, P);
      node := XMLDoc.ChildNodes.FindNode(S);
      while (node <> nil) and (P > 0) do
      Begin
        P := Pos('/', Chemin);
        if (P > 0) then
        Begin
          S := Copy(Chemin, 1, P - 1);
          delete(Chemin, 1, P);
        End else S := Chemin;
     
        if (P > 0) then // Si ce n'est pas le dernière identifiant, c'est un alors un noeud
        Begin
          node := node.ChildNodes.FindNode(S);
        End else
        Begin
          if node.HasAttribute(S) then result := node.GetAttributeNS(S, '') else node := nil;
        End;
      End;
    End;
    Voici toutes les fonctions que je me suis faite pour simplifier la vie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Function XMLRead(XMLDoc: TXMLDocument; Chemin, default: String): String;
    Function XMLReadInt(XMLDoc: TXMLDocument; Chemin:string; default: Integer): Integer;
    Procedure XMLWrite(XMLDoc: TXMLDocument; Path, item, Value: String);
    Procedure XMLWriteInt(XMLDoc: TXMLDocument; Path,item:string; Value: Integer);
    Procedure XMLSaveToFile(Xml: TXMLDocument; Fname: string);
    function XMLLoadFromFile(Xml: TXMLDocument; Fname: string;ShowErrNotFound: Boolean): Boolean;
    Function XMLClear(XMLDoc: TXMLDocument; Chemin: String):boolean;
    Function XMLReadInFile(FName:String;Chemin, default: String): String;
    Si tu les veux je te les envoies


    Franck

  3. #3
    Membre Expert

    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2007
    Messages
    3 530
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 530
    Par défaut réponse partielle pour commencer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    var
      xml: IXMLDocument;
      node: ixmlnode;
    begin
      xml := NewXMLDocument;
      node := xml.AddChild('Dossier');
      node.Attributes['xmlns:xsi'] := '"http://www.w3.org/2001/XMLSchema-instance"';
      node.Attributes['xmlns'] := '"http://onaya.net/InterApp/Datas"';
      memo1.Lines.Add(xml.XML.Text);
      xml := nil;

  4. #4
    Membre Expert

    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2007
    Messages
    3 530
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 530
    Par défaut
    Pour retrouver facilement un node par un chemin complet jene sais pas si ça existe mais une fonction de 5 lignes suffit:

    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
     
    function NodeOnPath(NodeBase: IXMLNode; NodePath: array of string): IXMLNode;
    var
      I: Integer;
    begin
      Result := NodeBase;
      for I  := Low(NodePath) to High(NodePath) do
      begin
        Result := Result.ChildNodes.FindNode(NodePath[I]);
        if Result = nil then
          Break;
      end;
    end;
     
    ...
     
      node.AddChild('niveau1').AddChild('niveau2');
     
      node.ChildNodes
        .nodes['niveau1'].ChildNodes
          .nodes['niveau2'].NodeValue := 'toto';
     
      node := NodeOnPath(node, ['niveau1', 'niveau2']);
    et quand il y a des longues lignes, ne pas oublier qu'on toujours mettre ça sur plusieurs lignes et indenter le code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
      with XML.ChildNodes.Nodes['Dossier']
            .ChildNodes.Nodes['Documents']
              .ChildNodes.Nodes['Document']
                .ChildNodes.Nodes['ContenuDocument']
                  .ChildNodes.Nodes['Ligne_Document'] do
      begin
        AddChild('Visible').Text := 'true';
        AddChild('Quantite').Text := '1.00';
    	end;
    ça rend les choses plus lisibles

  5. #5
    Membre Expert

    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2007
    Messages
    3 530
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 530
    Par défaut
    à défaut, une site très intéressant :

    https://theroadtodelphi.com/2013/05/...remonkey-apps/

  6. #6
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 76
    Par défaut
    Merci pour vos réponses et cela m'a permis d'avancer sur mon projet.

    Par contre je rencontre le soucis suivant :

    je dois obtenir un fichier xml comme ci-dessous :

    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
     
    <?xml version="1.0" encoding="UTF-8"?>
    -<Dossier>
         -<Ligne>
              -<Info>
                   <Valeur>valeur n°1</Valeur>
              </Info>
         <Ligne/>
         -<Ligne>
              -<Info>
                   <Valeur>valeur n°2</Valeur>
              </Info>
         </Ligne>
         -<Ligne>
              -<Info>
                   <Valeur>valeur n°3</Valeur>
              </Info>
         <Ligne/>
    </Dossier>
    Voici le code mis en place dans ma fiche Delphi

    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
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      i : integer;
    begin
      XMLDoc.Active := true;
      XMLdoc.Version := '1.0';
      XMLdoc.Encoding := 'UTF-8';
      XMLdoc.AddChild('Dossier');
     
      with XMLdoc.ChildNodes.Nodes['Dossier'] do
      begin
        for i := 1 to 3 do
        begin
          AddChild('Ligne');
          with XMLdoc.ChildNodes.Nodes['Dossier'].ChildNodes.Nodes['Ligne'] do
          begin
            AddChild('Info');
            with XMLdoc.ChildNodes.Nodes['Dossier'].ChildNodes.Nodes['Ligne'].ChildNodes.Nodes['Info'] do
              AddChild('Valeur').Text := 'valeur n°' + IntToStr(i);
          end;
        end;
      end;
      XMLDoc.SaveToFile('.\test.xml');
    end;
    Malheureusement avec ce dernier j'obtiens le résultat suivant :

    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
     
    <?xml version="1.0" encoding="UTF-8"?>
     
    -<Dossier>
         -<Ligne>
              -<Info>
                   <Valeur>valeur n°1</Valeur>
                   <Valeur>valeur n°2</Valeur>
                   <Valeur>valeur n°3</Valeur>
              </Info>
              <Info/>
              <Info/>
         </Ligne>
         <Ligne/>
         <Ligne/>
    </Dossier>
    Je n'arrive pas à savoir d'où provient mon erreur dans le code. Comment lui dire d'inscrire les données valeur et info dans chaque balise ligne ??

    Merci d'avance pour votre aide précieuse

  7. #7
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 76
    Par défaut
    j'ai réussi à trouver le code à mettre en place pour obtenir le résultat souhaité

    Voici le code :

    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
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      i : integer;
    begin
      XMLDoc.Active := true;
      XMLdoc.Version := '1.0';
      XMLdoc.Encoding := 'UTF-8';
      XMLdoc.AddChild('Dossier');
      with XMLdoc.ChildNodes.Nodes['Dossier'] do
      begin
        for i := 1 to 3 do
        begin
          AddChild('Ligne');
          with XMLdoc.ChildNodes.Nodes['Dossier'].ChildNodes.Last do
          begin
            AddChild('Info');
            with XMLdoc.ChildNodes.Nodes['Dossier'].ChildNodes.Last.ChildNodes.Last do
              AddChild('Valeur').Text := 'valeur n°' + IntToStr(i);
          end;
        end;
      end;
      XMLDoc.SaveToFile('.\test.xml');
    end;
    J'obtiens le résultat souhaité lors de la création de mon fichier xml par contre pensez-vous que ce code soit le plus optimal ?

Discussions similaires

  1. [MOSS 2007] Création automatique fichier XML pour BDC
    Par frechy dans le forum SharePoint
    Réponses: 6
    Dernier message: 06/03/2009, 11h11
  2. [DTD] Création de fichier XML
    Par ZeKiD dans le forum Format d'échange (XML, JSON...)
    Réponses: 7
    Dernier message: 20/02/2008, 15h27
  3. [DOM] création de fichier XML avec PHP
    Par cortex007 dans le forum Bibliothèques et frameworks
    Réponses: 7
    Dernier message: 09/12/2007, 11h31
  4. création de fichier xml : indentation du code généré
    Par DonKnacki dans le forum VBScript
    Réponses: 4
    Dernier message: 07/11/2007, 13h45
  5. [XSLT] Création de fichier XML dynamique avec PHP
    Par daninho dans le forum Bibliothèques et frameworks
    Réponses: 10
    Dernier message: 02/02/2006, 11h18

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