Skip to content

Commit d60e687

Browse files
BUG: to_xml with index=False and offset input index (#42464)
1 parent bb6de10 commit d60e687

File tree

3 files changed

+53
-6
lines changed

3 files changed

+53
-6
lines changed

doc/source/whatsnew/v1.3.1.rst

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Fixed regressions
2929
Bug fixes
3030
~~~~~~~~~
3131
- Fixed bug in :meth:`DataFrame.transpose` dropping values when the DataFrame had an Extension Array dtype and a duplicate index (:issue:`42380`)
32+
- Fixed bug in :meth:`DataFrame.to_xml` raising ``KeyError`` when called with ``index=False`` and an offset index (:issue:`42458`)
3233
-
3334

3435
.. ---------------------------------------------------------------------------

pandas/io/formats/xml.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -195,14 +195,18 @@ def handle_indexes(self) -> None:
195195
This method will add indexes into attr_cols or elem_cols.
196196
"""
197197

198+
if not self.index:
199+
return
200+
201+
first_key = next(iter(self.frame_dicts))
198202
indexes: list[str] = [
199-
x for x in self.frame_dicts[0].keys() if x not in self.orig_cols
203+
x for x in self.frame_dicts[first_key].keys() if x not in self.orig_cols
200204
]
201205

202-
if self.attr_cols and self.index:
206+
if self.attr_cols:
203207
self.attr_cols = indexes + self.attr_cols
204208

205-
if self.elem_cols and self.index:
209+
if self.elem_cols:
206210
self.elem_cols = indexes + self.elem_cols
207211

208212
def get_prefix_uri(self) -> str:
@@ -307,7 +311,7 @@ def build_tree(self) -> bytes:
307311
self.elem_row = SubElement(self.root, f"{self.prefix_uri}{self.row_name}")
308312

309313
if not self.attr_cols and not self.elem_cols:
310-
self.elem_cols = list(self.frame_dicts[0].keys())
314+
self.elem_cols = list(self.d.keys())
311315
self.build_elems()
312316

313317
else:
@@ -477,7 +481,7 @@ def build_tree(self) -> bytes:
477481
self.elem_row = SubElement(self.root, f"{self.prefix_uri}{self.row_name}")
478482

479483
if not self.attr_cols and not self.elem_cols:
480-
self.elem_cols = list(self.frame_dicts[0].keys())
484+
self.elem_cols = list(self.d.keys())
481485
self.build_elems()
482486

483487
else:

pandas/tests/io/xml/test_to_xml.py

+43-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111

1212
import pandas.util._test_decorators as td
1313

14-
from pandas import DataFrame
14+
from pandas import (
15+
DataFrame,
16+
Index,
17+
)
1518
import pandas._testing as tm
1619

1720
from pandas.io.common import get_handle
@@ -290,6 +293,45 @@ def test_index_false_rename_row_root(datapath, parser):
290293
assert output == expected
291294

292295

296+
@pytest.mark.parametrize(
297+
"offset_index", [list(range(10, 13)), [str(i) for i in range(10, 13)]]
298+
)
299+
def test_index_false_with_offset_input_index(parser, offset_index):
300+
"""
301+
Tests that the output does not contain the `<index>` field when the index of the
302+
input Dataframe has an offset.
303+
304+
This is a regression test for issue #42458.
305+
"""
306+
307+
expected = """\
308+
<?xml version='1.0' encoding='utf-8'?>
309+
<data>
310+
<row>
311+
<shape>square</shape>
312+
<degrees>360</degrees>
313+
<sides>4.0</sides>
314+
</row>
315+
<row>
316+
<shape>circle</shape>
317+
<degrees>360</degrees>
318+
<sides/>
319+
</row>
320+
<row>
321+
<shape>triangle</shape>
322+
<degrees>180</degrees>
323+
<sides>3.0</sides>
324+
</row>
325+
</data>"""
326+
327+
offset_geom_df = geom_df.copy()
328+
offset_geom_df.index = Index(offset_index)
329+
output = offset_geom_df.to_xml(index=False, parser=parser)
330+
output = equalize_decl(output)
331+
332+
assert output == expected
333+
334+
293335
# NA_REP
294336

295337
na_expected = """\

0 commit comments

Comments
 (0)