diff --git a/VERSIONS_WIP/73934 b/VERSIONS_WIP/73934
new file mode 100644
index 0000000000000000000000000000000000000000..31603ef9d455b0120faf62e3baf4b6c1ed2a92c5
--- /dev/null
+++ b/VERSIONS_WIP/73934
@@ -0,0 +1 @@
+ - ticket #73934 : Cosmogramme : ajout de la possibilité d'intégrer des ressources OAI en mode fichier.
\ No newline at end of file
diff --git a/library/Class/Cosmogramme/FileParser.php b/library/Class/Cosmogramme/FileParser.php
index c7c74cd5079bf020c7f3760b265168c597920775..8f29f0670a18600ef64207afd0c60e95e2290de8 100644
--- a/library/Class/Cosmogramme/FileParser.php
+++ b/library/Class/Cosmogramme/FileParser.php
@@ -23,26 +23,20 @@
  * Bokeh translation from cosmogramme API cosmogramme/php/classes/classe_parseur.php
  */
 abstract class Class_Cosmogramme_FileParser {
-  use Trait_StaticFileSystem;
-
-  const FORMAT_UNIMARC = 0;
-  const FORMAT_ASCII_TAB = 1;
-  const FORMAT_ASCII_COMMA = 2;
-  const FORMAT_ASCII_PIPE = 3;
-  const FORMAT_XML = 4;
-  const FORMAT_CSV = 5;
-  const FORMAT_MARC21 = 6;
-  const FORMAT_AVENIO = 8;
+  use Trait_StaticFileSystem, Trait_Translator;
 
   protected static $_format_parsers =
-    [self::FORMAT_UNIMARC => 'Marc',
-     self::FORMAT_ASCII_TAB => 'Ascii_Tab',
-     self::FORMAT_ASCII_COMMA => 'Ascii_Comma',
-     self::FORMAT_ASCII_PIPE => 'Ascii_Pipe',
-     self::FORMAT_XML => 'Xml',
-     self::FORMAT_CSV => 'Csv',
-     self::FORMAT_MARC21 => 'Marc',
-     self::FORMAT_AVENIO => 'Ascii_Tab'];
+    [
+     Class_IntProfilDonnees::FORMAT_UNIMARC          => 'Marc',
+     Class_IntProfilDonnees::FORMAT_TABBED_ASCII     => 'Ascii_Tab',
+     Class_IntProfilDonnees::FORMAT_SEMI_COLON_ASCII => 'Ascii_Comma',
+     Class_IntProfilDonnees::FORMAT_PIPED_ASCII      => 'Ascii_Pipe',
+     Class_IntProfilDonnees::FORMAT_XML              => 'XmlPatrons',
+     Class_IntProfilDonnees::FORMAT_CSV              => 'Csv',
+     Class_IntProfilDonnees::FORMAT_MARC21           => 'Marc',
+     Class_IntProfilDonnees::FORMAT_AVENIO           => 'Ascii_Tab',
+     Class_IntProfilDonnees::FORMAT_BIBLIONDEMAND    => 'OaiDC',
+    ];
 
   protected $_file_handle, $_position, $_file_size, $_profil;
   protected $_errors = [];
@@ -51,7 +45,7 @@ abstract class Class_Cosmogramme_FileParser {
   public static function openFor($file, $position, $profil) {
     $format = $profil->getFormat();
     if (!in_array($format, array_keys(static::$_format_parsers)))
-      throw new RuntimeException('Format ' . $format . ' non pris en charge');
+      throw new RuntimeException($this->_('Format %s non pris en charge', $format));
 
     $class = 'Class_Cosmogramme_FileParser_' . static::$_format_parsers[$format];
     return new $class($file, $position, $profil);
@@ -59,25 +53,22 @@ abstract class Class_Cosmogramme_FileParser {
 
 
   public function __construct($file, $position, $profil) {
+    $this->_buffer = '';
+    $this->_position = $position;
+    $this->_profil = $profil;
+
     $fileSystem = $this->getFileSystem();
-    $this->_file_handle = @$fileSystem->fopen($file, 'rb');
-    if (!$this->_file_handle) {
-      $this->_errors[] = 'Impossible d\'ouvrit le fichier :' . $file;
-      return false;
-    }
 
-    $this->_position = $position;
-    $this->_goto($position);
+    if (false === ($this->_file_handle = @$fileSystem->fopen($file, 'rb')))
+      return;
 
-    $this->_buffer = '';
+    $this->_goto($position);
     $this->_file_size = $fileSystem->filesize($file);
-    $this->_profil = $profil;
-    return true;
   }
 
 
   public function isValid() {
-    return empty($this->_errors);
+    return false !== $this->_file_handle;
   }
 
 
@@ -133,7 +124,7 @@ class Class_Cosmogramme_FileParser_Marc extends Class_Cosmogramme_FileParser {
         break;
       }
 
-      $record = $fileSystem->fread($this->_file_handle, self::READ_SIZE);
+      $record = $fileSystem->fread($this->_file_handle, static::READ_SIZE);
       if ($fileSystem->feof($this->_file_handle)
           && !$record) {
         $at_end = true;
@@ -203,22 +194,15 @@ class Class_Cosmogramme_FileParser_Ascii_Pipe extends Class_Cosmogramme_FilePars
 
 
 
+
 class Class_Cosmogramme_FileParser_Xml extends Class_Cosmogramme_FileParser {
   const READ_SIZE = 1024;
 
   protected $_xml_separator;
 
-  public function __construct($file, $position, $profil) {
-    parent::__construct($file, $position, $profil);
-    if (!$this->isValid())
-      return;
 
-    $data = $profil->getAttributs();
-    $attributs = unserialize($data);
-    $this->_xml_separator = $attributs[5]['xml_balise_abonne'];
-    if (!$this->_xml_separator) {
-      $this->_errors[] = 'La balise Xml qui sépare les enregistrements n\'est pas définie.';
-    }
+  public function isValid() {
+    return parent::isValid() && $this->_xml_separator;
   }
 
 
@@ -261,9 +245,19 @@ class Class_Cosmogramme_FileParser_Xml extends Class_Cosmogramme_FileParser {
 }
 
 
+class Class_Cosmogramme_FileParser_XmlPatrons extends Class_Cosmogramme_FileParser_Xml {
+  public function __construct($file, $position, $profil) {
+    parent::__construct($file, $position, $profil);
+    $this->_xml_separator = $profil->getXmlPatronField();
+  }
+}
+
+
+class Class_Cosmogramme_FileParser_OaiDC extends Class_Cosmogramme_FileParser_Xml {
+  protected $_xml_separator = 'record';
+}
+
 
 class Class_Cosmogramme_FileParser_Csv extends Class_Cosmogramme_FileParser_Ascii {
   protected $_separator = ',';
-}
-
-?>
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/library/Class/Cosmogramme/Integration/Record/Bibliondemand.php b/library/Class/Cosmogramme/Integration/Record/Bibliondemand.php
index 4cd5ae5d08f21bdbe565f518402eb65b06c503f7..2f03f6068ec37b0cefa7c79b720e6fe880daf75e 100644
--- a/library/Class/Cosmogramme/Integration/Record/Bibliondemand.php
+++ b/library/Class/Cosmogramme/Integration/Record/Bibliondemand.php
@@ -21,6 +21,16 @@
 
 
 class Class_Cosmogramme_Integration_Record_Bibliondemand extends Class_Cosmogramme_Integration_Record_DublinCore {
+
+
+  protected function _parseDatas($data) {
+    if (is_array($data))
+      return $data;
+    $parser = new Class_WebService_OAI_DublinCoreParser_Bibliondemand();
+    return $parser->parse($data)[0];
+  }
+
+
   protected function _dublinCoreToUnimarc() {
     $visitor = parent::_dublinCoreToUnimarc();
     $visitor
diff --git a/library/Class/Cosmogramme/Integration/Record/DublinCore.php b/library/Class/Cosmogramme/Integration/Record/DublinCore.php
index d79e9d5efe51f89df87732f14764f6ea4f5aa447..f08e60b4ecf796143865a675d14a87ab5c1c4925 100644
--- a/library/Class/Cosmogramme/Integration/Record/DublinCore.php
+++ b/library/Class/Cosmogramme/Integration/Record/DublinCore.php
@@ -32,6 +32,7 @@ class Class_Cosmogramme_Integration_Record_DublinCore extends notice_unimarc {
 
   public function ouvrirNotice($data, $id_data_profile, $sigb, $type_doc_force) {
     $this->_profil = Class_IntProfilDonnees::find($id_data_profile);
+    $data = $this->_parseDatas($data);
     $this->_types = $data['type'];
     $this->_formats = $data['format'];
     $this->_datas = $data;
@@ -40,10 +41,17 @@ class Class_Cosmogramme_Integration_Record_DublinCore extends notice_unimarc {
     return parent::ouvrirNotice($unimarc, $id_data_profile, $sigb, $type_doc_force);
   }
 
+  protected function _parseDatas($data) {
+    return $data;
+  }
 
   protected function _dublinCoreToUnimarc() {
     $authors = $this->_authorsFrom($this->_datas['auteur']);
 
+    $first_language=is_array($this->_datas['language'])
+      ? reset($this->_datas['language'])
+      : $this->_datas['language'];
+
     $unimarc_visitor = new Class_Indexation_PseudoNotice_UnimarcVisitor();
     $unimarc_visitor
       ->visitIdNotice($this->_datas['id_oai'])
@@ -53,7 +61,7 @@ class Class_Cosmogramme_Integration_Record_DublinCore extends notice_unimarc {
       ->visitDescriptions($this->_datas['rights'])
       ->visitDescriptions($this->_datas['relation'])
       ->visitYear($this->_datas['date'])
-      ->visitLanguageId(reset($this->_datas['language']))
+      ->visitLanguageId($first_language)
       ->visitMatiere(implode(';', $this->_datas['matiere']))
       ->visitEditors($this->_datas['editeur'])
       ->visitItems($this->_getItem())
diff --git a/tests/library/Class/Cosmogramme/Integration/RecordPhaseBibliondemandTest.php b/tests/library/Class/Cosmogramme/Integration/PhaseNoticeBibliondemandTest.php
similarity index 84%
rename from tests/library/Class/Cosmogramme/Integration/RecordPhaseBibliondemandTest.php
rename to tests/library/Class/Cosmogramme/Integration/PhaseNoticeBibliondemandTest.php
index d6492daf41de1ec64253741bfdb8802ada9a1bac..af82ba170a6f6b330faa0a07068f45e175844a90 100644
--- a/tests/library/Class/Cosmogramme/Integration/RecordPhaseBibliondemandTest.php
+++ b/tests/library/Class/Cosmogramme/Integration/PhaseNoticeBibliondemandTest.php
@@ -22,7 +22,7 @@
 require_once('cosmogramme/php/fonctions/variables.php');
 require_once(__DIR__.'/PhaseNoticeTestCase.php');
 
-abstract class AbstractRecordPhaseBibliondemandTestCase extends PhaseNoticeTestCase {
+abstract class PhaseNoticeBibliondemandTestCase extends PhaseNoticeTestCase {
   protected $_storm_default_to_volatile = true;
 
   protected function _prepareFixtures() {
@@ -55,7 +55,22 @@ abstract class AbstractRecordPhaseBibliondemandTestCase extends PhaseNoticeTestC
                    ['id' => 3,
                     'nom_court' => 'Bibliondemand']);
 
-    Class_Cosmogramme_Integration::find(999)
+    $this->fixture('Class_Cosmogramme_Integration',
+                   ['id' => 888,
+                    'bib' => Class_IntBib::find(3),
+                    'profil_donnees' => Class_IntProfilDonnees::find(102),
+                    'type_operation' => Class_Cosmogramme_Integration::TYPE_OPERATION_TOTAL,
+                    'traite' => 'non',
+                    'fichier' => 'records.txt',
+                    'pointeur_reprise' => 0]);
+
+
+    $this->_prepareIntegration();
+  }
+
+
+  protected function _prepareIntegration() {
+    Class_Cosmogramme_Integration::find(888)
       ->setIdBib(3)
       ->setFichier('http://oai.bibliondemand.com/oaiserver.ashx?verb=ListRecords&metadataPrefix=oai_dc&set=CG62')
       ->save();
@@ -79,7 +94,7 @@ abstract class AbstractRecordPhaseBibliondemandTestCase extends PhaseNoticeTestC
 
 
 
-class RecordPhaseBibliondemandSimpleTest extends AbstractRecordPhaseBibliondemandTestCase {
+class PhaseNoticeBibliondemandSimpleTest extends PhaseNoticeBibliondemandTestCase {
   /** @test */
   public function logShouldNotContainsError() {
     $this->assertNotLogContains('Erreur');
@@ -214,17 +229,16 @@ class RecordPhaseBibliondemandSimpleTest extends AbstractRecordPhaseBibliondeman
 
 
 
-
-class RecordPhaseBibliondemandUpdateTest extends AbstractRecordPhaseBibliondemandTestCase {
+class PhaseNoticeBibliondemandUpdateTest extends PhaseNoticeBibliondemandTestCase {
   public function _prepareFixtures() {
     parent::_prepareFixtures();
 
-    Class_Cosmogramme_Integration::find(999)
+    Class_Cosmogramme_Integration::find(888)
       ->beIncrementImport()
       ->save();
 
 
-  $record = $this->fixture('Class_Notice',
+    $record = $this->fixture('Class_Notice',
                              ['id' => 1,
                               'type_doc' => 16,
                               'alpha_titre' => 'PIERO SOFFICI',
@@ -260,4 +274,29 @@ class RecordPhaseBibliondemandUpdateTest extends AbstractRecordPhaseBibliondeman
   public function typeDocShouldStay16() {
     $this->assertEquals(16, $this->_record->getTypeDoc());
   }
+}
+
+
+
+
+class PhaseNoticeBibliondemandSimpleFileTest extends PhaseNoticeBibliondemandSimpleTest {
+
+  protected function _prepareIntegration() {
+    Class_Cosmogramme_Integration::find(888)
+      ->setIdBib(3)
+      ->setFichier('Bibliondemand.xml')
+      ->save();
+  }
+}
+
+
+
+class PhaseNoticeBibliondemandUpdateFileTest extends PhaseNoticeBibliondemandUpdateTest {
+
+  protected function _prepareIntegration() {
+    Class_Cosmogramme_Integration::find(888)
+      ->setIdBib(3)
+      ->setFichier('Bibliondemand.xml')
+      ->save();
+  }
 }
\ No newline at end of file
diff --git a/tests/library/Class/Cosmogramme/Integration/PhasePrepareIntegrationsTest.php b/tests/library/Class/Cosmogramme/Integration/PhasePrepareIntegrationsTest.php
index fd524be7fbed5724ff46a383a323355cf6427d40..62a1a3a5d8e07165f5cd7f2d54ee4f7119126bfd 100644
--- a/tests/library/Class/Cosmogramme/Integration/PhasePrepareIntegrationsTest.php
+++ b/tests/library/Class/Cosmogramme/Integration/PhasePrepareIntegrationsTest.php
@@ -19,40 +19,41 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
-abstract class PhasePrepareIntegrationsWithOAITestCase extends Class_Cosmogramme_Integration_PhaseTestCase {
+abstract class PhasePrepareIntegrationsWithOAITestCase
+  extends Class_Cosmogramme_Integration_PhaseTestCase {
+
   protected $_http_client;
 
   public function setUp() {
     parent::setUp();
 
-    $file_system = Storm_Test_ObjectWrapper::mock();
-    $file_system
-      ->whenCalled('is_file')
-      ->with ('ftp/my-library.net/transferts/foo/mylibrarytotal.txt')
-      ->answers(true)
+    $file_system = $this->mock()
+                        ->whenCalled('is_file')
+                        ->with ('ftp/my-library.net/transferts/foo/mylibrarytotal.txt')
+                        ->answers(true)
 
-      ->whenCalled('is_file')
-      ->with ('ftp/my-library.net/transferts/foo/mylibraryincr.txt')
-      ->answers(false)
+                        ->whenCalled('is_file')
+                        ->with ('ftp/my-library.net/transferts/foo/mylibraryincr.txt')
+                        ->answers(false)
 
-      ->whenCalled('opendir')
-      ->with ('ftp/my-library.net/transferts/foo/')
-      ->answers('dir_pointer')
+                        ->whenCalled('opendir')
+                        ->with ('ftp/my-library.net/transferts/foo/')
+                        ->answers('dir_pointer')
 
 
-      ->whenCalled('readdir')
-      ->with ('dir_pointer')
-      ->answers('mylibraryincr.txt')
+                        ->whenCalled('readdir')
+                        ->with ('dir_pointer')
+                        ->answers('mylibraryincr.txt')
 
-      ->whenCalled('closedir')
-      ->with ('dir_pointer')
-      ->answers(true)
+                        ->whenCalled('closedir')
+                        ->with ('dir_pointer')
+                        ->answers(true)
 
-      ->whenCalled('rename')
-      ->with('ftp/my-library.net/transferts/foo/mylibrarytotal.txt',
-             'ftp/my-library.net/integration/integre1179.pan')
-      ->answers(true)
-      ->beStrict();
+                        ->whenCalled('rename')
+                        ->with('ftp/my-library.net/transferts/foo/mylibrarytotal.txt',
+                               'ftp/my-library.net/integration/integre1179.pan')
+                        ->answers(true)
+                        ->beStrict();
 
     $this->_http_client = $this->mock()
                                ->whenCalled('postData')
@@ -73,6 +74,9 @@ abstract class PhasePrepareIntegrationsWithOAITestCase extends Class_Cosmogramme
 
   public function tearDown() {
     Class_Systeme_Report_Publication::resetHttpClient();
+    Class_Cosmogramme_Integration_PhasePrepareIntegrations::setFileSystem(null);
+    Class_Cosmogramme_Integration_PhasePrepareIntegrations::setTimeSource(null);
+
     parent::tearDown();
   }