From fe480fd82cf0bf4c9b146ed0d0dbbeccf26e13e8 Mon Sep 17 00:00:00 2001
From: pbarroca <pbarroca@afi-sa.fr>
Date: Wed, 2 Dec 2015 18:27:58 +0100
Subject: [PATCH] rel #33948 : new ilsdi record reader, Koha is not SAX safe

---
 VERSIONS_HOTLINE/33948                        |   1 +
 .../Class/WebService/SIGB/Koha/Exemplaire.php |   7 +-
 .../SIGB/Koha/GetRecordsResponseReader.php    | 241 ++++++++++++------
 .../Class/WebService/SIGB/Koha/Service.php    |  22 +-
 .../Class/WebService/SIGB/KohaTest.php        |  24 ++
 .../WebService/SIGB/pikoloco_record_7359.txt  | 168 ++++++++++++
 6 files changed, 367 insertions(+), 96 deletions(-)
 create mode 100644 VERSIONS_HOTLINE/33948
 create mode 100644 tests/library/Class/WebService/SIGB/pikoloco_record_7359.txt

diff --git a/VERSIONS_HOTLINE/33948 b/VERSIONS_HOTLINE/33948
new file mode 100644
index 00000000000..3c470515d72
--- /dev/null
+++ b/VERSIONS_HOTLINE/33948
@@ -0,0 +1 @@
+ - ticket #33948 : Koha/Pikoloco : Correction du calcul de la disponibilité des exemplaires
\ No newline at end of file
diff --git a/library/Class/WebService/SIGB/Koha/Exemplaire.php b/library/Class/WebService/SIGB/Koha/Exemplaire.php
index d6b786db6e2..dcac15af7a5 100644
--- a/library/Class/WebService/SIGB/Koha/Exemplaire.php
+++ b/library/Class/WebService/SIGB/Koha/Exemplaire.php
@@ -16,7 +16,7 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with BOKEH; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 class Class_WebService_SIGB_Koha_Exemplaire extends Class_WebService_SIGB_Exemplaire {
   protected $_endommage = false;
@@ -30,6 +30,7 @@ class Class_WebService_SIGB_Koha_Exemplaire extends Class_WebService_SIGB_Exempl
   public function setEndommage($flag) {
     $this->_endommage = (bool)$flag;
     $this->updateDisponibilite();
+    return $this;
   }
 
 
@@ -48,6 +49,7 @@ class Class_WebService_SIGB_Koha_Exemplaire extends Class_WebService_SIGB_Exempl
   public function setPerdu($flag) {
     $this->_perdu = (bool)$flag;
     $this->updateDisponibilite();
+    return $this;
   }
 
 
@@ -83,6 +85,7 @@ class Class_WebService_SIGB_Koha_Exemplaire extends Class_WebService_SIGB_Exempl
   public function setDateRetour($date_retour) {
     parent::setDateRetour($date_retour);
     $this->updateDisponibilite();
+    return $this;
   }
 
 
@@ -103,7 +106,7 @@ class Class_WebService_SIGB_Koha_Exemplaire extends Class_WebService_SIGB_Exempl
    */
   public function updateDisponibilite() {
     if (!$this->isPiege() and ('' != $this->getDateRetour()))
-        $this->setDisponibiliteEnPret();
+      $this->setDisponibiliteEnPret();
   }
 
 
diff --git a/library/Class/WebService/SIGB/Koha/GetRecordsResponseReader.php b/library/Class/WebService/SIGB/Koha/GetRecordsResponseReader.php
index 19fcb6655ad..34b15890816 100644
--- a/library/Class/WebService/SIGB/Koha/GetRecordsResponseReader.php
+++ b/library/Class/WebService/SIGB/Koha/GetRecordsResponseReader.php
@@ -18,35 +18,36 @@
  * along with BOKEH; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
+
 class Class_WebService_SIGB_Koha_GetRecordsResponseReader {
   use Class_WebService_SIGB_Koha_TraitFormat;
 
-  protected $_xml_parser;
-  protected $_notice;
-  protected $inderdire_resa_doc_dispo=false;
-  protected $_reservations = [];
-  protected $_not_for_loan_status = array(
-                                          0 => Class_WebService_SIGB_Exemplaire::DISPO_LIBRE,
-                                          1 => "Exclu du prêt",
-                                          2 => "En traitement",
-                                          3 => "Consultation sur place",
-                                          4 => "En réserve",
-                                          5 => "En réparation",
-                                          6 => "En reliure",
-                                          7 => "Exclu du prêt temporairement");
-
-  /**
-   * @var Class_WebService_SIGB_Koha_Exemplaire
-   */
-  protected $_current_exemplaire;
+  static protected $_default_reader;
+
+  protected $_record, $_item, $_holds = [];
+  protected $_cannot_hold_available = false;
+  protected $_not_for_loan_status = [0 => Class_WebService_SIGB_Exemplaire::DISPO_LIBRE,
+                                     1 => 'Exclu du prêt',
+                                     2 => 'En traitement',
+                                     3 => 'Consultation sur place',
+                                     4 => 'En réserve',
+                                     5 => 'En réparation',
+                                     6 => 'En reliure',
+                                     7 => 'Exclu du prêt temporairement'];
 
   public static function newInstance() {
     return new self();
   }
 
 
+  /** @category testing */
+  public static function setDefaultReader($reader) {
+    static::$_default_reader = $reader;
+  }
+
+
   public function setInterdireResaDocDispo($dispo) {
-    $this->interdire_resa_doc_dispo = $dispo;
+    $this->_cannot_hold_available = $dispo;
     return $this;
   }
 
@@ -54,118 +55,190 @@ class Class_WebService_SIGB_Koha_GetRecordsResponseReader {
   public function setCodificationDisponibilites($codif) {
     foreach($codif as $status => $libelle)
       $this->_not_for_loan_status[$status] = $libelle;
+
     return $this;
   }
 
 
+  public function allowAvailableDocumentReservation() {
+    return !$this->_cannot_hold_available;
+  }
+
+
   public function getNoticeFromXML($xml) {
-    $this->_xml_parser = Class_WebService_XMLParser::newInstance();
-    $this->_notice = new Class_WebService_SIGB_Notice(0);
-    $this->_xml_parser
-      ->setElementHandler($this)
-      ->parse($xml);
+    $this->_record = new Class_WebService_SIGB_Notice(0);
+    if (false === ($doc = $this->_getReader()->read($xml)))
+      return $this->_record;
+
+    if (!$record = $doc->record)
+      return $this->_record;
+
+    if ($id = $record->biblioitemnumber)
+      $this->_record->setId((string)$id);
 
-    return $this->_notice;
+    foreach($record->reserves->reserve as $xml_hold)
+      $this->_handleHold($xml_hold);
+
+    foreach($record->items->item as $xml_item)
+      $this->_handleItem($xml_item);
+
+    return $this->_record;
   }
 
 
-  public function allowAvailableDocumentReservation() {
-    return !$this->interdire_resa_doc_dispo;
+  protected function _handleHold($xml_hold) {
+    if ($this->_hasChild('itemnumber', $xml_hold))
+      $this->_holds[] = (string)$xml_hold->itemnumber;
   }
 
 
-  public function endBiblioItemNumber($data) {
-    if (!$this->_xml_parser->inParents('items'))
-      $this->_notice->setId($data);
+  protected function _handleItem($xml_item) {
+    $this->_item = new Class_WebService_SIGB_Koha_Exemplaire(null);
+    $this->_xml_item = $xml_item;
+
+    $this
+      ->_handleItemWithdrawn()
+      ->_handleItemNotForLoan()
+      ->_handleItemNumber()
+      ->_handleItemDateDue()
+      ->_handleItemBarCode()
+      ->_handleItemLost()
+      ->_handleItemDamaged()
+      ;
+
+    $this->_record->addExemplaire($this->_item);
   }
 
 
-  public function startItem($attributes) {
-    $this->_current_exemplaire = new Class_WebService_SIGB_Koha_Exemplaire(null);
+  protected function _handleItemBarCode() {
+    if ($this->_hasChild('barcode', $this->_xml_item))
+      $this->_item->setCodeBarre((string)$this->_xml_item->barcode);
+
+    return $this;
   }
 
 
-  public function endItem($data) {
-    $this->_notice->addExemplaire($this->_current_exemplaire);
+  protected function _handleItemDateDue() {
+    $date_due = '';
+    if ($this->_hasChild('date_due', $this->_xml_item)
+        && $date_due = (string)$this->_xml_item->date_due) {
+      $date = $this->formatDate($date_due);
+      $this->_item
+        ->setDateRetour($date)
+        ->setDisponibiliteEnPret();
+    }
+
+    if ($date_due || $this->allowAvailableDocumentReservation())
+      $this->_item->setReservable(true);
+
+    return $this;
   }
 
 
-  public function endBarCode($data) {
-    if ($this->_xml_parser->inParents('item'))
-      $this->_current_exemplaire->setCodeBarre($data);
+  protected function _handleItemWithdrawn() {
+    // different koha versions compatibility
+    return $this
+      ->_handleWithdrawnNamed('withdrawn')
+      ->_handleWithdrawnNamed('wthdrawn');
   }
 
 
-  public function endDate_Due($data) {
-    if (!$this->_xml_parser->inParents('item'))
-      return;
+  protected function _handleWithdrawnNamed($name) {
+    if (!$this->_hasChild($name, $this->_xml_item))
+      return $this;
 
-    $date = $this->formatDate($data);
-    $this->_current_exemplaire->setDateRetour($date);
+    if ('0' != (string)$this->_xml_item->{$name})
+      $this->_item
+        ->setRetire(true)
+        ->setDisponibilitePilonne();
 
-    if (('' != $date)  || ($this->allowAvailableDocumentReservation()))
-      $this->_current_exemplaire->setReservable(true);
+    return $this;
   }
 
 
-  public function endWthdrawn($data) {
-    if (!$this->_xml_parser->inParents('item'))
-      return;
+  protected function _handleItemLost() {
+    if ($this->_hasChild('itemlost', $this->_xml_item)
+        && '0' !== (string)$this->_xml_item->itemlost)
+      $this->_item
+        ->setPerdu(true)
+        ->setDisponibilitePerdu();
 
-    if (0 != $data) {
-      $this->_current_exemplaire->setRetire(true);
-      $this->_current_exemplaire->setDisponibilitePilonne();
-    }
+    return $this;
   }
 
 
-  public function endItemlost($data) {
-    if (!$this->_xml_parser->inParents('item'))
-      return;
+  protected function _handleItemDamaged() {
+    if ($this->_hasChild('damaged', $this->_xml_item)
+        && '0' !== (string)$this->_xml_item->damaged)
+      $this->_item->setEndommage(true);
 
-    if (0 != $data) {
-      $this->_current_exemplaire->setPerdu(true);
-      $this->_current_exemplaire->setDisponibilitePerdu();
-
-    }
+    return $this;
   }
 
 
-  public function endDamaged($data) {
-    if (!$this->_xml_parser->inParents('item'))
-      return;
+  protected function _handleItemNotForLoan() {
+    if (!$this->_hasChild('notforloan', $this->_xml_item))
+      return $this;
 
-    if (0 != $data)
-      $this->_current_exemplaire->setEndommage(true);
+    $data = (string)$this->_xml_item->notforloan;
+    if (!array_key_exists($data, $this->_not_for_loan_status)
+        || $this->_item->isPiege())
+      return $this;
+
+    if (!in_array($data, ['0', '4']))
+      $this->_item->notForLoan();
+
+    if ('' == $this->_item->getDateRetour())
+      $this->_item->setDisponibilite($this->_not_for_loan_status[$data]);
+
+    return $this;
   }
 
 
-  public function endNotForLoan($data) {
-    if (!$this->_xml_parser->inParents('item'))
-      return;
+  protected function _handleItemNumber() {
+    if (!$this->_hasChild('itemnumber', $this->_xml_item))
+      return $this;
 
-    if (array_key_exists($data, $this->_not_for_loan_status) and !$this->_current_exemplaire->isPiege()) {
-      $this->_current_exemplaire->setDisponibilite($this->_not_for_loan_status[$data]);
-      if (!in_array($data, array('0', '4')))
-        $this->_current_exemplaire->notForLoan();
+    $data = (string)$this->_xml_item->itemnumber;
+    $this->_item->setId($data);
+    if ($this->_isHeld($data)) {
+      $this->_item
+        ->setDisponibiliteDejaReserve()
+        ->setReservable(true);
     }
+
+    return $this;
   }
 
 
-  public function endItemNumber($data) {
-    if ($this->_xml_parser->inParents('reserve')) {
-      $this->_reservations[] = $data;
-      return;
-    }
+  protected function _isHeld($id) {
+    return in_array($id, $this->_holds);
+  }
 
-    if ($this->_xml_parser->inParents('item')) {
-      $this->_current_exemplaire->setId($data);
-      if (in_array($data, $this->_reservations)) {
-        $this->_current_exemplaire->setDisponibiliteDejaReserve();
-        $this->_current_exemplaire->setReservable(true);
-      }
-    }
+
+  protected function _getReader() {
+    return static::$_default_reader
+      ? static::$_default_reader
+      : new Class_WebService_SIGB_Koha_GetRecordsResponseReaderXmlReader();
+  }
+
+
+  protected function _hasChild($name, $node) {
+    foreach($node->children() as $child)
+      if ($child->getName() == $name)
+        return true;
+    return false;
   }
 }
 
-?>
\ No newline at end of file
+
+
+class Class_WebService_SIGB_Koha_GetRecordsResponseReaderXmlReader {
+  public function read($xml) {
+    libxml_use_internal_errors(true);
+    $document = simplexml_load_string($xml);
+    libxml_use_internal_errors(false);
+
+    return $document;
+  }
+}
\ No newline at end of file
diff --git a/library/Class/WebService/SIGB/Koha/Service.php b/library/Class/WebService/SIGB/Koha/Service.php
index dc9a329a9d9..350b2a2e029 100644
--- a/library/Class/WebService/SIGB/Koha/Service.php
+++ b/library/Class/WebService/SIGB/Koha/Service.php
@@ -206,12 +206,17 @@ class Class_WebService_SIGB_Koha_Service extends Class_WebService_SIGB_AbstractR
 
 
   public function getNotice($id) {
-    return $this->ilsdiGetRecords($id,
-                                  Class_WebService_SIGB_Koha_GetRecordsResponseReader::newInstance()
-                                  ->setCodificationDisponibilites($this->codification_disponibilites)
-                                  ->setInterdireResaDocDispo($this->interdire_resa_doc_dispo));
+    return $this->ilsdiGetRecords($id, $this->_getReader());
   }
 
+
+  protected function _getReader() {
+    return Class_WebService_SIGB_Koha_GetRecordsResponseReader::newInstance()
+      ->setCodificationDisponibilites($this->codification_disponibilites)
+      ->setInterdireResaDocDispo($this->interdire_resa_doc_dispo);
+  }
+
+
   public function test() {
     $validator = new ZendAfi_Validate_Url();
     if (!$validator->isValid($this->getServerRoot()))
@@ -225,19 +230,16 @@ class Class_WebService_SIGB_Koha_Service extends Class_WebService_SIGB_AbstractR
         $message .= $response->getStatus() . " " . $response->getMessage()
           . "\n\n" . $response->getBody();
       return $message;
-      } catch (Exception $e) {
+
+    } catch (Exception $e) {
       return $e->getMessage() . '\n' . $e->getTraceAsString();
     }
   }
 
 
-
   public function newBuySuggestForm() {
     return $this->providesSuggestions()
       ? new Class_WebService_SIGB_Koha_BuySuggestForm()
       : parent::newBuySuggestForm();
   }
-
-}
-
-?>
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/tests/library/Class/WebService/SIGB/KohaTest.php b/tests/library/Class/WebService/SIGB/KohaTest.php
index ccf2bbb1cc8..8f6ec4af38a 100644
--- a/tests/library/Class/WebService/SIGB/KohaTest.php
+++ b/tests/library/Class/WebService/SIGB/KohaTest.php
@@ -1025,3 +1025,27 @@ class KohaServicePatroninfoReaderWithNoLibTest extends KohaTestCase {
     $this->assertEmpty($this->laurent->getLibraryLabel());
   }
 }
+
+
+/** @see http://forge.afi-sa.fr/issues/33948 */
+class KohaServiceGetRecordPikolocoTest extends KohaTestCase {
+  protected $record;
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->mock_web_client
+      ->whenCalled('open_url')
+      ->with('http://cat-aficg55.biblibre.com/cgi-bin/koha/ilsdi.pl?service=GetRecords&id=7359')
+      ->answers(file_get_contents(__DIR__ . '/pikoloco_record_7359.txt'));
+
+    $this->record = $this->service->getNotice(7359);
+  }
+
+
+  /** @test */
+  public function itemShouldNotBeAvailable() {
+    $this->assertNotEquals('Disponible',
+                           $this->record->exemplaireAt(0)->getDisponibilite());
+  }
+}
\ No newline at end of file
diff --git a/tests/library/Class/WebService/SIGB/pikoloco_record_7359.txt b/tests/library/Class/WebService/SIGB/pikoloco_record_7359.txt
new file mode 100644
index 00000000000..85ac07a9603
--- /dev/null
+++ b/tests/library/Class/WebService/SIGB/pikoloco_record_7359.txt
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<GetRecords>
+  <record>
+    <pages>527 p.</pages>
+    <cn_sort></cn_sort>
+    <itemtype>Texte impr</itemtype>
+    <issues>
+      <issue>
+        <author>Régine Deforges</author>
+        <itemnumber>7677</itemnumber>
+        <title>Alger, ville blanche</title>
+        <date_due>2015-09-01 23:59:00</date_due>
+        <auto_renew>0</auto_renew>
+        <barcode>RARE000336</barcode>
+        <cardnumber>RARE000023</cardnumber>
+        <issuedate>2015-08-11 16:37:00</issuedate>
+        <firstname>Denise</firstname>
+        <onsite_checkout>0</onsite_checkout>
+        <branchcode>RARECOURT</branchcode>
+        <surname>HAVETTE</surname>
+        <biblionumber>7359</biblionumber>
+        <borrowernumber>159</borrowernumber>
+        <timestamp>2015-08-11 16:37:04</timestamp>
+      </issue>
+    </issues>
+    <items>
+      <item>
+        <booksellerid>AUTRE</booksellerid>
+        <onloan>2015-09-01</onloan>
+        <cn_sort>R_DEF_A</cn_sort>
+        <issues>1</issues>
+        <barcode>RARE000336</barcode>
+        <holdingbranch>RARECOURT</holdingbranch>
+        <damaged>0</damaged>
+        <ccode>ROMANS</ccode>
+        <datelastseen>2015-08-11</datelastseen>
+        <itemlost>0</itemlost>
+        <biblioitemnumber>7359</biblioitemnumber>
+        <datelastborrowed>2015-08-11</datelastborrowed>
+        <itemnumber>7677</itemnumber>
+        <location>ADULTE</location>
+        <itype>LIV</itype>
+        <date_due>2015-09-01 23:59:00</date_due>
+        <holdingbranchname>Espace Culturel de Rarecourt</holdingbranchname>
+        <itemcallnumber>R DEF a</itemcallnumber>
+        <cardnumber>RARE000023</cardnumber>
+        <homebranchname>Espace Culturel de Rarecourt</homebranchname>
+        <itemnotes>La bicyclette bleue 8 - Saga familiale</itemnotes>
+        <withdrawn>0</withdrawn>
+        <biblionumber>7359</biblionumber>
+        <notforloan>0</notforloan>
+        <dateaccessioned>2014-12-18</dateaccessioned>
+        <timestamp>2015-08-11 16:37:04</timestamp>
+        <borrowernumber>159</borrowernumber>
+        <homebranch>RARECOURT</homebranch>
+      </item>
+    </items>
+    <publishercode>Éd. France loisirs</publishercode>
+    <biblioitemnumber>7359</biblioitemnumber>
+    <size>21 cm</size>
+    <volume>1959-1960</volume>
+    <reserves>
+    </reserves>
+    <isbn>2744151610</isbn>
+    <collectiontitle> La  bicyclette bleue</collectiontitle>
+    <publicationyear>2002</publicationyear>
+    <marcxml>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;record
+    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
+    xsi:schemaLocation=&quot;http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd&quot;
+    xmlns=&quot;http://www.loc.gov/MARC21/slim&quot;&gt;
+
+  &lt;leader&gt;00832cam a2200241   4500&lt;/leader&gt;
+  &lt;controlfield tag=&quot;001&quot;&gt;7359&lt;/controlfield&gt;
+  &lt;datafield tag=&quot;010&quot; ind1=&quot; &quot; ind2=&quot; &quot;&gt;
+    &lt;subfield code=&quot;a&quot;&gt;2744151610&lt;/subfield&gt;
+    &lt;subfield code=&quot;b&quot;&gt;rel.&lt;/subfield&gt;
+    &lt;subfield code=&quot;d&quot;&gt;15,10 EUR&lt;/subfield&gt;
+  &lt;/datafield&gt;
+  &lt;datafield tag=&quot;020&quot; ind1=&quot; &quot; ind2=&quot; &quot;&gt;
+    &lt;subfield code=&quot;a&quot;&gt;FR&lt;/subfield&gt;
+    &lt;subfield code=&quot;b&quot;&gt;00227467&lt;/subfield&gt;
+  &lt;/datafield&gt;
+  &lt;datafield tag=&quot;090&quot; ind1=&quot; &quot; ind2=&quot; &quot;&gt;
+    &lt;subfield code=&quot;a&quot;&gt;7359&lt;/subfield&gt;
+  &lt;/datafield&gt;
+  &lt;datafield tag=&quot;100&quot; ind1=&quot; &quot; ind2=&quot; &quot;&gt;
+    &lt;subfield code=&quot;a&quot;&gt;20020809d2002    m  y0frey50      ba&lt;/subfield&gt;
+  &lt;/datafield&gt;
+  &lt;datafield tag=&quot;101&quot; ind1=&quot;0&quot; ind2=&quot; &quot;&gt;
+    &lt;subfield code=&quot;a&quot;&gt;fre&lt;/subfield&gt;
+  &lt;/datafield&gt;
+  &lt;datafield tag=&quot;102&quot; ind1=&quot; &quot; ind2=&quot; &quot;&gt;
+    &lt;subfield code=&quot;a&quot;&gt;FR&lt;/subfield&gt;
+  &lt;/datafield&gt;
+  &lt;datafield tag=&quot;105&quot; ind1=&quot; &quot; ind2=&quot; &quot;&gt;
+    &lt;subfield code=&quot;a&quot;&gt;    z   00 a &lt;/subfield&gt;
+  &lt;/datafield&gt;
+  &lt;datafield tag=&quot;106&quot; ind1=&quot; &quot; ind2=&quot; &quot;&gt;
+    &lt;subfield code=&quot;a&quot;&gt;r&lt;/subfield&gt;
+  &lt;/datafield&gt;
+  &lt;datafield tag=&quot;200&quot; ind1=&quot;1&quot; ind2=&quot; &quot;&gt;
+    &lt;subfield code=&quot;a&quot;&gt;Alger, ville blanche&lt;/subfield&gt;
+    &lt;subfield code=&quot;b&quot;&gt;Texte imprimé&lt;/subfield&gt;
+    &lt;subfield code=&quot;e&quot;&gt;1959-1960&lt;/subfield&gt;
+    &lt;subfield code=&quot;f&quot;&gt;Régine Deforges&lt;/subfield&gt;
+  &lt;/datafield&gt;
+  &lt;datafield tag=&quot;210&quot; ind1=&quot; &quot; ind2=&quot; &quot;&gt;
+    &lt;subfield code=&quot;a&quot;&gt;Paris&lt;/subfield&gt;
+    &lt;subfield code=&quot;c&quot;&gt;Éd. France loisirs&lt;/subfield&gt;
+    &lt;subfield code=&quot;d&quot;&gt;2002&lt;/subfield&gt;
+    &lt;subfield code=&quot;e&quot;&gt;86-Ligugé&lt;/subfield&gt;
+    &lt;subfield code=&quot;e&quot;&gt;Impr. Aubin&lt;/subfield&gt;
+  &lt;/datafield&gt;
+  &lt;datafield tag=&quot;215&quot; ind1=&quot; &quot; ind2=&quot; &quot;&gt;
+    &lt;subfield code=&quot;a&quot;&gt;527 p.&lt;/subfield&gt;
+    &lt;subfield code=&quot;c&quot;&gt;jaquette ill. en coul.&lt;/subfield&gt;
+    &lt;subfield code=&quot;d&quot;&gt;21 cm&lt;/subfield&gt;
+  &lt;/datafield&gt;
+  &lt;datafield tag=&quot;225&quot; ind1=&quot;1&quot; ind2=&quot;9&quot;&gt;
+    &lt;subfield code=&quot;a&quot;&gt; La  bicyclette bleue&lt;/subfield&gt;
+  &lt;/datafield&gt;
+  &lt;datafield tag=&quot;300&quot; ind1=&quot; &quot; ind2=&quot; &quot;&gt;
+    &lt;subfield code=&quot;a&quot;&gt;En appendice, entretien avec Régine Deforges&lt;/subfield&gt;
+  &lt;/datafield&gt;
+  &lt;datafield tag=&quot;461&quot; ind1=&quot; &quot; ind2=&quot;0&quot;&gt;
+    &lt;subfield code=&quot;0&quot;&gt;34308953&lt;/subfield&gt;
+    &lt;subfield code=&quot;t&quot;&gt; La  Bicyclette bleue&lt;/subfield&gt;
+  &lt;/datafield&gt;
+  &lt;datafield tag=&quot;686&quot; ind1=&quot; &quot; ind2=&quot; &quot;&gt;
+    &lt;subfield code=&quot;2&quot;&gt;Cadre de classement de la Bibliographie nationale française&lt;/subfield&gt;
+  &lt;/datafield&gt;
+  &lt;datafield tag=&quot;700&quot; ind1=&quot; &quot; ind2=&quot; &quot;&gt;
+    &lt;subfield code=&quot;3&quot;&gt;11899083&lt;/subfield&gt;
+    &lt;subfield code=&quot;a&quot;&gt;Deforges&lt;/subfield&gt;
+    &lt;subfield code=&quot;b&quot;&gt;Régine&lt;/subfield&gt;
+    &lt;subfield code=&quot;f&quot;&gt;1935-2014&lt;/subfield&gt;
+    &lt;subfield code=&quot;4&quot;&gt;070&lt;/subfield&gt;
+  &lt;/datafield&gt;
+  &lt;datafield tag=&quot;801&quot; ind1=&quot; &quot; ind2=&quot;0&quot;&gt;
+    &lt;subfield code=&quot;a&quot;&gt;FR&lt;/subfield&gt;
+    &lt;subfield code=&quot;b&quot;&gt;FR-751131015&lt;/subfield&gt;
+    &lt;subfield code=&quot;c&quot;&gt;20020809&lt;/subfield&gt;
+    &lt;subfield code=&quot;g&quot;&gt;AFNOR&lt;/subfield&gt;
+    &lt;subfield code=&quot;2&quot;&gt;intermrc&lt;/subfield&gt;
+  &lt;/datafield&gt;
+  &lt;datafield tag=&quot;995&quot; ind1=&quot; &quot; ind2=&quot; &quot;&gt;
+    &lt;subfield code=&quot;2&quot;&gt;0&lt;/subfield&gt;
+    &lt;subfield code=&quot;3&quot;&gt;0&lt;/subfield&gt;
+    &lt;subfield code=&quot;9&quot;&gt;7677&lt;/subfield&gt;
+    &lt;subfield code=&quot;a&quot;&gt;AUTRE&lt;/subfield&gt;
+    &lt;subfield code=&quot;b&quot;&gt;RARECOURT&lt;/subfield&gt;
+    &lt;subfield code=&quot;c&quot;&gt;RARECOURT&lt;/subfield&gt;
+    &lt;subfield code=&quot;e&quot;&gt;ADULTE&lt;/subfield&gt;
+    &lt;subfield code=&quot;f&quot;&gt;RARE000336&lt;/subfield&gt;
+    &lt;subfield code=&quot;h&quot;&gt;ROMANS&lt;/subfield&gt;
+    &lt;subfield code=&quot;k&quot;&gt;R DEF a&lt;/subfield&gt;
+    &lt;subfield code=&quot;n&quot;&gt;2015-09-01&lt;/subfield&gt;
+    &lt;subfield code=&quot;o&quot;&gt;0&lt;/subfield&gt;
+    &lt;subfield code=&quot;r&quot;&gt;LIV&lt;/subfield&gt;
+    &lt;subfield code=&quot;u&quot;&gt;La bicyclette bleue 8 - Saga familiale&lt;/subfield&gt;
+  &lt;/datafield&gt;
+&lt;/record&gt;
+</marcxml>
+    <biblionumber>7359</biblionumber>
+    <timestamp>2014-12-18 16:34:57</timestamp>
+  </record>
+</GetRecords>
-- 
GitLab