Les fichiers à plat sont des fichiers textuels possédant une structure ordonnée à l'image notamment, des fichiers de configurations (ini) ou des fichiers statistiques (log).

Les données contenues dans ce genre de fichiers peuvent être facilement extraites du fait de leur parfaite organisation.

212.30.116.74 GET /coursasp/formulaire.html HTTP/1.1 200 11085
216.206.88.135 GET /coursvbscript/sommaire.html HTTP/1.0 200 11660
...

Chaque champ dans cet exemple, est délimité par un espace blanc et chaque ligne par un saut de ligne (chr(10)) et un retour chariot (chr(13)). Le caractère de délimitation pourrait être n'importe quel caractère comme une virgule (,) ou un point-virgule (;).

Il est possible de rencontrer d'autres types de fichiers à plat comme ceux à largeur fixe ou à enregistrements balisés.

Les fichiers à largeur fixe diffère dans la mesure où chaque champ possède un nombre d'octets déterminé.

212.30.116.74  GET  /coursasp/formulaire.html    HTTP/1.1 200 11085
...
' 15 octets 4 octets 50 octets 8 octets 3 octets 6 octets chr(10) chr(13)
...

Les fichiers à enregistrements balisés contiennent un balisage spécifique représentant un type d'information pour chacune des lignes.

H 212.30.116.74 GET /coursasp/formulaire.html HTTP/1.1 200 11085
J 212.30.116.74 GET /javascript/initialisation.js HTTP/1.1" 200 9065
J 212.30.116.74 GET /coursasp/javascript/navigation.js HTTP/1.1 200 2517
S 212.30.116.74 GET /style/sommaire.css HTTP/1.1 200 1332
...
' P représente une page HTML,
' J représente un script externe,
' S représente une feuille de style.

Avant d'écrire un programme permettant d'extraire les informations précisément, il est impératif d'analyser attentivement la structure du fichier à plat afin de définir non seulement son type mais aussi les délimiteurs, les champs et les lignes.

65.116.145.133 - - "GET,/coursjavascript/style.html,HTTP/1.1" 200 16169
212.30.116.74 - - "GET,/javascript/initialisation.js,HTTP/1.1" 200 9065
...

Dans ce cas, les délimiteurs ne sont pas identiques pour tous les champs bien qu'il s'agisse d'un fichier à plat délimité.

Subséquemment à l'étude du fichier, il est nécessaire d'établir un dictionnaire des données comportant l'emplacement du champ dans la ligne, son nom, son type de données, ses valeurs possibles et éventuellement une description.

Num (délimiteur) Nom
Type Valeurs
Description
1 ( - - ") adresse_ip
chaîne ###.###.###.###
Adresse IP du client comportant 9 chiffres et trois points.
2 (,) methode
chaîne POST | GET
Méthodes d'accès au serveur.
3 (,) document
chaîne [/répertoire][...]/document.extension
Adresse locale du document.
4 (" ) protocole
chaîne HTTP/1.1
Protocole d'accès HTTP.
5 ( ) code
numérique ###
Code d'accès HTTP à trois chiffres.
6 (saut de ligne) poids
numérique ######
Poids du document en octets.

Ensuite, il faut penser à étudier la structure d'accueil pour les informations extraites du fichier à plat.

Pour un fichier XML, l'élément racine, les éléments parents et enfants ainsi que les attributs doivent être déterminés de sorte à convenir le plus judcieusement possible aux contraintes d'une application.

<statistique>
  <client adresse_ip="valeur">
    <document poids="valeur"
                   protocole="valeur"
                   code="valeur"
                   methode="valeur">
      valeur
    </document>
    <document poids="valeur"
                   protocole="valeur"
                   code="valeur"
                   methode="valeur">
      valeur
    </document>
    ...
  </client>
  ...
</statistique>

Il ne reste désormais plus qu'à entreprendre l'élaboration d'un programme permettant de sérialiser automatiquement un fichier à plat en fichier XML.

Exemple [voir]
<%
  Const OpenFileForReading = 1

  Dim obj_fso, obj_dom, obj_log, racine, noeud
  Dim obj_client, obj_document, obj_protocole, obj_code, obj_methode
  Dim adresse_ip, methode, document, protocole, code, poids
  Dim tableau, elt_adresse, i, trouve
  i = 1

  Set obj_fso = Server.CreateObject("Scripting.FileSystemObject")
  fichier = Server.MapPath("fichier_log.txt")
  Set obj_log = obj_fso.OpenTextFile(fichier, OpenFileForReading)

  Set obj_dom = Server.CreateObject("MSXML2.DOMDocument")
  Set racine = obj_dom.createElement("statistique")
  obj_dom.appendChild racine

  Do While Not obj_log.AtEndOfStream
    trouve = false
    ligne = obj_log.ReadLine
    tableau = Split(ligne, " ", -1, 1)
    elt_adresse = Split(tableau(3), ",", -1, 1)

    adresse_ip = tableau(0)
    methode = Right(elt_adresse(0), Len(elt_adresse(0)) - 1)
    document = elt_adresse(1)
    protocole = Left(elt_adresse(2), Len(elt_adresse(2)) - 1)
    code = tableau(4)
    poids = tableau(5)

    Set obj_client = obj_dom.createElement("client")
    obj_client.setAttribute "adresse_ip", adresse_ip

    Set obj_document = obj_dom.createElement("document")
    Set document_txt = obj_dom.createTextNode(document)
    obj_document.setAttribute "poids", poids
    obj_document.setAttribute "protocole", protocole
    obj_document.setAttribute "code", code
    obj_document.setAttribute "methode", methode

    obj_document.appendChild document_txt

    Response.Write "<br><b>Ligne n°" & i & "</b><br>---------<br>" & adresse_ip _
                 & "<br>" & methode & "<br>" & document & "<br>" _
                 & protocole & "<br>" & code & "<br>" & poids & "<br><br>"

    If racine.hasChildNodes Then
      For Each noeud In racine.childNodes
        If noeud.attributes.item(0).value = adresse_ip Then
          Response.Write i & " " & noeud.nodeName & " : " _
                           & noeud.attributes.item(0).value _
                           & " = " & adresse_ip & "<br>"

          noeud.appendChild obj_document

          trouve = true
        End If
        i = i + 1
      Next
    End If

    If trouve = false OR (racine.hasChildNodes AND trouve = false) Then
      obj_client.appendChild obj_document

      racine.appendChild obj_client
    End If

    i = i + 1
  Loop

  obj_dom.save(Server.MapPath("fichier_log.xml"))

  Response.Write "Le fichier de statistique au format texte" _
                 & " est disponible à l'adresse suivante :<br>" _
                 & Server.MapPath("fichier_log.xml")

  obj_log.close
  Set obj_log = Nothing
%>
Sommaire