diff --git a/pandas/io/formats/xml.py b/pandas/io/formats/xml.py
index 5725975bb6278..ee19f27fe8df6 100644
--- a/pandas/io/formats/xml.py
+++ b/pandas/io/formats/xml.py
@@ -251,18 +251,11 @@ def other_namespaces(self) -> dict:
"""
nmsp_dict: dict[str, str] = {}
- if self.namespaces and self.prefix is None:
- nmsp_dict = {
- "xmlns": n # noqa: RUF011
- for p, n in self.namespaces.items()
- if p != ""
- }
-
- if self.namespaces and self.prefix:
+ if self.namespaces:
nmsp_dict = {
- "xmlns": n # noqa: RUF011
+ f"xmlns{p if p=='' else f':{p}'}": n
for p, n in self.namespaces.items()
- if p == ""
+ if n != self.prefix_uri[1:-1]
}
return nmsp_dict
@@ -365,16 +358,16 @@ def build_tree(self) -> bytes:
elem_row = self.build_attribs(d, elem_row)
self.build_elems(d, elem_row)
- self.out_xml = tostring(self.root, method="xml", encoding=self.encoding)
+ self.out_xml = tostring(
+ self.root,
+ method="xml",
+ encoding=self.encoding,
+ xml_declaration=self.xml_declaration,
+ )
if self.pretty_print:
self.out_xml = self.prettify_tree()
- if self.xml_declaration:
- self.out_xml = self.add_declaration()
- else:
- self.out_xml = self.remove_declaration()
-
if self.stylesheet is not None:
raise ValueError(
"To use stylesheet, you need lxml installed and selected as parser."
@@ -395,8 +388,10 @@ def get_prefix_uri(self) -> str:
uri = f"{{{self.namespaces[self.prefix]}}}"
except KeyError:
raise KeyError(f"{self.prefix} is not included in namespaces")
- else:
+ elif "" in self.namespaces:
uri = f'{{{self.namespaces[""]}}}'
+ else:
+ uri = ""
return uri
@@ -418,31 +413,6 @@ def prettify_tree(self) -> bytes:
return dom.toprettyxml(indent=" ", encoding=self.encoding)
- def add_declaration(self) -> bytes:
- """
- Add xml declaration.
-
- This method will add xml declaration of working tree. Currently,
- xml_declaration is supported in etree starting in Python 3.8.
- """
- decl = f'\n'
-
- return (
- self.out_xml
- if self.out_xml.startswith(b" bytes:
- """
- Remove xml declaration.
-
- This method will remove xml declaration of working tree. Currently,
- pretty_print is not supported in etree.
- """
-
- return self.out_xml.split(b"?>")[-1].strip()
-
class LxmlXMLFormatter(BaseXMLFormatter):
"""
@@ -513,8 +483,10 @@ def get_prefix_uri(self) -> str:
uri = f"{{{self.namespaces[self.prefix]}}}"
except KeyError:
raise KeyError(f"{self.prefix} is not included in namespaces")
- else:
+ elif "" in self.namespaces:
uri = f'{{{self.namespaces[""]}}}'
+ else:
+ uri = ""
return uri
diff --git a/pandas/tests/io/xml/test_to_xml.py b/pandas/tests/io/xml/test_to_xml.py
index ebd52a21a00fe..a6ed15f56d8d4 100644
--- a/pandas/tests/io/xml/test_to_xml.py
+++ b/pandas/tests/io/xml/test_to_xml.py
@@ -154,7 +154,6 @@ def equalize_decl(doc):
'
+
+
+ 0
+ square
+ 360
+ 4.0
+
+
+ 1
+ circle
+ 360
+
+
+
+ 2
+ triangle
+ 180
+ 3.0
+
+"""
+
+ output = geom_df.to_xml(
+ namespaces={"oth": "http://other.org", "ex": "http://example.com"},
+ parser=parser,
+ )
+ output = equalize_decl(output)
+
+ assert output == expected
+
+
# PREFIX
@@ -750,7 +782,7 @@ def test_missing_prefix_in_nmsp(parser, geom_df):
def test_namespace_prefix_and_default(parser, geom_df):
expected = """\
-
+
0
square
@@ -778,13 +810,6 @@ def test_namespace_prefix_and_default(parser, geom_df):
)
output = equalize_decl(output)
- if output is not None:
- # etree and lxml differs on order of namespace prefixes
- output = output.replace(
- 'xmlns:doc="http://other.org" xmlns="http://example.com"',
- 'xmlns="http://example.com" xmlns:doc="http://other.org"',
- )
-
assert output == expected