none
Traitement de ficher XML RRS feed

  • Question

  • Bonjour,

    J'aimerais savoir si il est possible de traiter des fichiers XML assez simplement.

    Mon fichier XML contient un résumé de plusieurs appels (Numéro du poste, numéro du correspondant, temps de communication , date , sens de l'appel,...

    tout mes appels sont répertoriés dans un seul et même fichiers.

    Représentationd'un appel dans le fichier :

    	<CallAccounting xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="CAPTicket_V001.001.xsd">*
    		<OmniPCXOffice>
    			<SoftwareVersion>3EH30369BVAA ALZQO510/023.004</SoftwareVersion>
    			<CPUIPAddress>192.168.92.246</CPUIPAddress>
    		</OmniPCXOffice>
    		<Checksum>550119011</Checksum>
    		<TicketType>Call</TicketType>
    		<ChargedUserType>A</ChargedUserType>
    		<ChargedUserID>101</ChargedUserID>
    		<SubscriberName>PO</SubscriberName>
    		<CommunicationType>Outgoing</CommunicationType>
    		<TrunkType>N</TrunkType>
    		<TrunkID>001</TrunkID>
    		<Date>2008-08-08</Date>
    		<Time>22:44:00</Time>
    		<CallDuration>00:27:01</CallDuration>
    		<TaxesAmount>0</TaxesAmount>
    		<Service>ST</Service>
    		<DialledNumber>0156412361</DialledNumber>
    		<DialledMode>M</DialledMode>
    		<RingingDuration>00:00:00</RingingDuration>
    		<Cost>0.00</Cost>
    		<Currency>EUR</Currency>
    	</CallAccounting>
    

    Représentation du fichier:

    <?xml version="1.0" encoding="UTF-8"?>
    <CallAcoutingList>
    	<CallAccounting xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="CAPTicket_V001.001.xsd">*
    		<OmniPCXOffice>
    			<SoftwareVersion>3EH30369BVAA ALZQO510/023.004</SoftwareVersion>
    			<CPUIPAddress>192.168.92.246</CPUIPAddress>
    		</OmniPCXOffice>
    		<Checksum>550119011</Checksum>
    		<TicketType>Call</TicketType>
    		<ChargedUserType>A</ChargedUserType>
    		<ChargedUserID>100</ChargedUserID>
    		<SubscriberName>PO</SubscriberName>
    		<CommunicationType>Outgoing</CommunicationType>
    		<TrunkType>N</TrunkType>
    		<TrunkID>001</TrunkID>
    		<Date>2007-06-15</Date>
    		<Time>13:37:00</Time>
    		<CallDuration>00:00:25</CallDuration>
    		<TaxesAmount>0</TaxesAmount>
    		<Service>ST</Service>
    		<DialledNumber>0156412361</DialledNumber>
    		<DialledMode>M</DialledMode>
    		<RingingDuration>00:00:00</RingingDuration>
    		<Cost>0.00</Cost>
    		<Currency>EUR</Currency>
    	</CallAccounting>
    	<CallAccounting xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="CAPTicket_V001.001.xsd">*
    		<OmniPCXOffice>
    			<SoftwareVersion>3EH30369BVAA ALZQO510/023.004</SoftwareVersion>
    			<CPUIPAddress>192.168.92.246</CPUIPAddress>
    		</OmniPCXOffice>
    		<Checksum>550119011</Checksum>
    		<TicketType>Call</TicketType>
    		<ChargedUserType>A</ChargedUserType>
    		<ChargedUserID>101</ChargedUserID>
    		<SubscriberName>PO</SubscriberName>
    		<CommunicationType>Outgoing</CommunicationType>
    		<TrunkType>N</TrunkType>
    		<TrunkID>001</TrunkID>
    		<Date>2008-08-08</Date>
    		<Time>22:44:00</Time>
    		<CallDuration>00:27:01</CallDuration>
    		<TaxesAmount>0</TaxesAmount>
    		<Service>ST</Service>
    		<DialledNumber>0156412361</DialledNumber>
    		<DialledMode>M</DialledMode>
    		<RingingDuration>00:00:00</RingingDuration>
    		<Cost>0.00</Cost>
    		<Currency>EUR</Currency>
    	</CallAccounting>
    </CallAccountingList>
    	
    

     

    Donc enfaite, je voudrais regarder si le numéro du poste correspond à une de mes variables déjà entrée au préalable.Puis ensuite capturer le temps d'appel, le numéro, la date et l'heure du même appel (donc sans remonter dans l'arborescence).

     

    Si vous pouvez m'aider pour traiter mon fichier XML

     

    Cordialement,

    Jérémy T

     


    Jérémy
    mercredi 15 juin 2011 12:52

Réponses

  • Bonjour,

    voici un exemple pour vous aider dans l'interrogation du xml.

    La variable chargedUserId contient l'id du poste que vous pourrez alimenter ensuite via une zone de saisie.

    Dans l'exemple le xml doit être présent au même niveau que l'exécutable sinon libre à vous de changer le chemin

    Ensuite via des méthodes LINQ to Xml on filtre les éléments pour ne retenir que ceux concernant l'Id recherché et de type sortant

    Juste pour l'exemple l'affichage est effectué dans une messageBox


    // id user qui peut être alimenté par une textbox
    string chargedUserID = "100";
    string lineMessage = null;
    
    // chargement du fichier xml
    XDocument xDoc = XDocument.Load("./data.xml");
    
    // recherche des éléments pour lesquels
    // ChargedUserID = ID du poste
    // CommunicationType = Outgoing
    IEnumerable<XElement> elements =
     xDoc.Elements("CallAcoutingList")
     .Elements("CallAccounting")
     .Where(
     el => el.Element("ChargedUserID").Value == chargedUserID &&
     el.Element("CommunicationType").Value == "Outgoing");
    
    // boucle sur les éléments retenus
    foreach (XElement el in elements)
    {
     lineMessage = String.Format("Date {0}, Time {1}, CallDuration {2}, DialledNumber {3}",
      el.Element("Date").Value,
      el.Element("Time").Value,
      el.Element("CallDuration").Value,
      el.Element("DialledNumber").Value);
    
     MessageBox.Show(lineMessage);
    }
    

    Cordialement
    • Marqué comme réponse JérémyT jeudi 16 juin 2011 11:25
    mercredi 15 juin 2011 16:44
    Modérateur
  • Prenez peut être un peu de temps pour vous familiariser avec le language en lisant l'article suivant :

    Comment : concaténer plusieurs chaînes (Guide de programmation C#)

    Une simple concaténation de chaine peut répondre à votre besoin

    string nom = "nom";
    string prenom = "prenom";
    string fileName = "C:\\Projet\\Facture\\" + nom + "_" + prenom + ".txt";
       //ou
    string fileNameBis = String.Format("C:\\Projet\\Facture\\{0}_{1}.txt",nom ,prenom);
    

    Cordialement

    • Marqué comme réponse JérémyT jeudi 16 juin 2011 13:22
    jeudi 16 juin 2011 09:24
    Modérateur

Toutes les réponses

  • Bonjour,

    pour parcourir et effectuer des recherche dans le Xml vous pouvez utiliser Linq To Xml. La classe de base à utiliser  dans ce cas sera XDocument. Cette classe contiendra votre Xml ( voir la méthode Load ) et sera utiliser pour rechercher les informations.

    Sinon précisez votre demande : a quel élément Xml correspond excatement "le numéro de poste", DialNumber ? Dans ce cas quel est l'élément pour récupérer l'information "numéro" ? Faut-il prévoir de pouvoir de récupérer plusieurs appels pour un "numéro de poste" ?

    Cordialement

     

    mercredi 15 juin 2011 13:10
    Modérateur
  • je devrais effectuer cette recherche lors de l'appui sur un bouton qui ouvre le fichier et qui le traite.

    effectivement il peux avoir plusieurs appels par postes.

     

     ChargedUserID => Numérro du poste
    CommunicationType => Sens de l'appel (il faut qu'il soit en "Outgoing" pour pouvoir le traiter sinon c est un appel reçu donc pas besoin)
    Date => la date de l'appel Time=> l'heure de l'appel CallDuration => Temps de l'appel
    DialledNumber=> Numéro du correspondant

    Jérémy
    mercredi 15 juin 2011 15:40
  • Bonjour,

    voici un exemple pour vous aider dans l'interrogation du xml.

    La variable chargedUserId contient l'id du poste que vous pourrez alimenter ensuite via une zone de saisie.

    Dans l'exemple le xml doit être présent au même niveau que l'exécutable sinon libre à vous de changer le chemin

    Ensuite via des méthodes LINQ to Xml on filtre les éléments pour ne retenir que ceux concernant l'Id recherché et de type sortant

    Juste pour l'exemple l'affichage est effectué dans une messageBox


    // id user qui peut être alimenté par une textbox
    string chargedUserID = "100";
    string lineMessage = null;
    
    // chargement du fichier xml
    XDocument xDoc = XDocument.Load("./data.xml");
    
    // recherche des éléments pour lesquels
    // ChargedUserID = ID du poste
    // CommunicationType = Outgoing
    IEnumerable<XElement> elements =
     xDoc.Elements("CallAcoutingList")
     .Elements("CallAccounting")
     .Where(
     el => el.Element("ChargedUserID").Value == chargedUserID &&
     el.Element("CommunicationType").Value == "Outgoing");
    
    // boucle sur les éléments retenus
    foreach (XElement el in elements)
    {
     lineMessage = String.Format("Date {0}, Time {1}, CallDuration {2}, DialledNumber {3}",
      el.Element("Date").Value,
      el.Element("Time").Value,
      el.Element("CallDuration").Value,
      el.Element("DialledNumber").Value);
    
     MessageBox.Show(lineMessage);
    }
    

    Cordialement
    • Marqué comme réponse JérémyT jeudi 16 juin 2011 11:25
    mercredi 15 juin 2011 16:44
    Modérateur
  • et les valeurs des appels différents il sont stoker où?


    Jérémy
    mercredi 15 juin 2011 19:34
  • cela pourrait être n'importe ou : xml, base de données, simple affichage dans une grille ... Dans l'exemple ils sont affichés via la MessageBox au final c'est à vous de voir ce que vous voulez en faire c'est votre projet :)

     


    mercredi 15 juin 2011 19:47
    Modérateur
  • donc pour le mettre dans un fichier a la place de MessageBox.Show(lineMessage) , il suffit que j'entre lineMessage dans un fichier avec StreamWriter ?


    Jérémy
    mercredi 15 juin 2011 21:10
  • Je viens de tester ton bout de programme , mais il y a une erreur durant l’exécution du code (pas a la compilation, mais quand je rentre dans la form).

     

    Message d'erreur :

    La balise de début 'CallAcoutingList' sur la ligne 2 à la position 2 ne correspond pas à la balise de fin de 'CallAccountingList'. Ligne 312, position 3.

     

    Voici le code :

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Xml.Linq;
    
    namespace taxatel
    {
      public partial class Payer : Form
      {
        public string NumPoste = "";
        SuitePayer FormSuitePayer = new SuitePayer();//Créer une nouvelle Form
        public Payer()
        {
          InitializeComponent();
        }
    
        private void ValPayer_Click(object sender, EventArgs e)
        {
          FormSuitePayer.Show();//Affiche la form "SuitePayer".
          this.Hide();//Cache la Form active.
          string chargedUserID = NumPoste;
          string lineMessage = null;
    
          // chargement du fichier xml
          XDocument xDoc = XDocument.Load("C:\\Projet\\TicketCollector.XML");
          // recherche des éléments pour lesquels
          // ChargedUserID = ID du poste
          // CommunicationType = Outgoing
          IEnumerable<XElement> elements = xDoc.Elements("CallAcoutingList").Elements("CallAccounting").Where(el => el.Element("ChargedUserID").Value == chargedUserID && el.Element("CommunicationType").Value == "Outgoing");
          // boucle sur les éléments retenus
          foreach (XElement el in elements)
          {
            lineMessage = String.Format("Date {0}, Time {1}, CallDuration {2}, DialledNumber {3}",
            el.Element("Date").Value,
            el.Element("Time").Value,
            el.Element("CallDuration").Value,
            el.Element("DialledNumber").Value);
    
            using (StreamWriter sw = new StreamWriter("C:\\Projet\\Facture_detail.txt", true)) //Ouverture en écriture du fichier ,Si non existant creation du fichier FicheClient.
            {
              sw.WriteLine(lineMessage);
            }
    
          }
        }
    
        private void PostePayer_TextChanged(object sender, EventArgs e)
        {
          NumPoste = this.PostePayer.Text;//Recupere la valeur de la textBox"PostePayer" dans la variable "NumPoste".
          
    
    
        }
    
        private void AnnPayer_Click(object sender, EventArgs e)
        {
          this.Hide();//Cache la Form active.
        }
      }
    }
    
    



    Jérémy
    jeudi 16 juin 2011 07:05
  • Le problème ne vient pas du programme mais de votre xml.

    <CallAcoutingList>
    ....</CallAccountingList>
    
    
    

    il manque a un "c" dans la balise ouvrante.

    jeudi 16 juin 2011 08:01
    Modérateur
  • Merci, mais la même erreur ...
    Jérémy
    jeudi 16 juin 2011 08:10
  • Si vous avez ajoutez un c et modifié également dans le code

    IEnumerable<XElement> elements = xDoc.Elements("CallAccoutingList")..........
    
    pour ma part cela fonctionne avec le xml suivant corrigé

     

    <?xml version="1.0" encoding="UTF-8"?>
    <CallAccoutingList>
     <CallAccounting xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="CAPTicket_V001.001.xsd">
     *
     <OmniPCXOffice>
      <SoftwareVersion>3EH30369BVAA ALZQO510/023.004</SoftwareVersion>
      <CPUIPAddress>192.168.92.246</CPUIPAddress>
     </OmniPCXOffice>
     <Checksum>550119011</Checksum>
     <TicketType>Call</TicketType>
     <ChargedUserType>A</ChargedUserType>
     <ChargedUserID>100</ChargedUserID>
     <SubscriberName>PO</SubscriberName>
     <CommunicationType>Outgoing</CommunicationType>
     <TrunkType>N</TrunkType>
     <TrunkID>001</TrunkID>
     <Date>2007-06-15</Date>
     <Time>13:37:00</Time>
     <CallDuration>00:00:25</CallDuration>
     <TaxesAmount>0</TaxesAmount>
     <Service>ST</Service>
     <DialledNumber>0156412361</DialledNumber>
     <DialledMode>M</DialledMode>
     <RingingDuration>00:00:00</RingingDuration>
     <Cost>0.00</Cost>
     <Currency>EUR</Currency>
     </CallAccounting>
     <CallAccounting xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="CAPTicket_V001.001.xsd">
     *
     <OmniPCXOffice>
      <SoftwareVersion>3EH30369BVAA ALZQO510/023.004</SoftwareVersion>
      <CPUIPAddress>192.168.92.246</CPUIPAddress>
     </OmniPCXOffice>
     <Checksum>550119011</Checksum>
     <TicketType>Call</TicketType>
     <ChargedUserType>A</ChargedUserType>
     <ChargedUserID>101</ChargedUserID>
     <SubscriberName>PO</SubscriberName>
     <CommunicationType>Outgoing</CommunicationType>
     <TrunkType>N</TrunkType>
     <TrunkID>001</TrunkID>
     <Date>2008-08-08</Date>
     <Time>22:44:00</Time>
     <CallDuration>00:27:01</CallDuration>
     <TaxesAmount>0</TaxesAmount>
     <Service>ST</Service>
     <DialledNumber>0156412361</DialledNumber>
     <DialledMode>M</DialledMode>
     <RingingDuration>00:00:00</RingingDuration>
     <Cost>0.00</Cost>
     <Currency>EUR</Currency>
     </CallAccounting>
    </CallAccoutingList>
    

     


    jeudi 16 juin 2011 08:14
    Modérateur
  • Oui, excusez moi il manquer un 'N' dans la balise ouvrante.

     

    Derniere question pour ce sujet, Pour créer un fichier puis-je mettre une variable dans un nom de chemin?


    Jérémy
    jeudi 16 juin 2011 08:25
  • Le mieux c'est d'essayer et oui rien ne vous empêche de créer une chaine avec cette variable et de l'utiliser dans le path de votre fichier.
    jeudi 16 juin 2011 09:01
    Modérateur
  • mais comment on fait??

    j'aimerais que mes fichier aille dans

    C:\\Projet\\Facture\\"Nomclient"_"PrenomClient"

    et mes variables seraient "Nomclient" et "PrenomClient".

     


    Jérémy
    jeudi 16 juin 2011 09:14
  • Prenez peut être un peu de temps pour vous familiariser avec le language en lisant l'article suivant :

    Comment : concaténer plusieurs chaînes (Guide de programmation C#)

    Une simple concaténation de chaine peut répondre à votre besoin

    string nom = "nom";
    string prenom = "prenom";
    string fileName = "C:\\Projet\\Facture\\" + nom + "_" + prenom + ".txt";
       //ou
    string fileNameBis = String.Format("C:\\Projet\\Facture\\{0}_{1}.txt",nom ,prenom);
    

    Cordialement

    • Marqué comme réponse JérémyT jeudi 16 juin 2011 13:22
    jeudi 16 juin 2011 09:24
    Modérateur