+ gr->target_sheet_name = NULL;
+
+ int current_row = -1;
+ int current_col = -1;
+
+ /* Spool to the target cell, caching values of cells as they are encountered. */
+ for (int ret = 1; ret; )
+ {
+ while ((ret = xmlTextReaderRead (sd.xtr)))
+ {
+ process_node (gr, &sd);
+ if (sd.state == STATE_CELL)
+ {
+ if (sd.current_sheet == n)
+ {
+ current_row = sd.row;
+ current_col = sd.col;
+ break;
+ }
+ }
+ }
+ if (current_row >= row && current_col >= column - 1)
+ break;
+
+ while ((ret = xmlTextReaderRead (sd.xtr)))
+ {
+ process_node (gr, &sd);
+ if (sd.node_type == XML_READER_TYPE_TEXT)
+ break;
+ }
+
+ if (use_cache)
+ {
+ /* See if this cell has already been cached ... */
+ unsigned int hash = hash_int (current_row, 0);
+ hash = hash_int (current_col, hash);
+ struct cache_datum *probe = NULL;
+ HMAP_FOR_EACH_WITH_HASH (probe, struct cache_datum, node, hash,
+ &gr->cache)
+ {
+ if (probe->row == current_row && probe->col == current_col)
+ break;
+ }
+ /* If not, then cache it. */
+ if (!probe)
+ {
+ char *str = CHAR_CAST (char *, xmlTextReaderValue (sd.xtr));
+ struct cache_datum *cell_data = XMALLOC (struct cache_datum);
+ cell_data->row = current_row;
+ cell_data->col = current_col;
+ cell_data->value = str;
+ hmap_insert (&gr->cache, &cell_data->node, hash);
+ }
+ }
+ }
+
+ while (xmlTextReaderRead (sd.xtr))
+ {
+ process_node (gr, &sd);
+ if (sd.state == STATE_CELL && sd.node_type == XML_READER_TYPE_TEXT)
+ {
+ if (sd.current_sheet == n)
+ {
+ if (row == sd.row && column == sd.col)
+ break;
+ }
+ }
+ }
+
+ char *cell_content = CHAR_CAST (char *, xmlTextReaderValue (sd.xtr));
+ xmlFreeTextReader (sd.xtr);
+ return cell_content;
+}