Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ElementTree adds spurious ns0: namespace prefix #113425

Open
dechamps opened this issue Dec 23, 2023 · 3 comments
Open

ElementTree adds spurious ns0: namespace prefix #113425

dechamps opened this issue Dec 23, 2023 · 3 comments
Labels
topic-XML type-bug An unexpected behavior, bug, or error

Comments

@dechamps
Copy link

dechamps commented Dec 23, 2023

Bug description:

Minimal reproducer

import xml.etree.ElementTree as ET

print(
    ET.tostring(ET.fromstring("<foo xmlns='somens'>a<bar /></foo>"), encoding="unicode")
)

Expected output

<foo xmlns="somens">a<bar /></foo>

Actual output

<ns0:foo xmlns:ns0="somens">a<ns0:bar /></ns0:foo>

Discussion

It would appear that, if a namespace isn't registered, ElementTree will use a ns0: namespace prefix by default during serialization, instead of simply using the default namespace.

Now to be fair, technically this is a valid thing to do, as the resulting XML is semantically the same. However I still find this behavior problematic because:

  1. It is confusing and violates the principle of least surprise. Users won't expect to see a random namespace prefix just popping out of nowhere.
  2. It unnecessarily increases the size of the resulting XML document.
  3. Most importantly, the use of namespace prefixes can cause problems with downstream consumers.
    • For example, the SVG viewer in VS Code and in the GitHub file browser get confused if an SVG file uses namespace prefixes. (This is how I stumbled upon this issue)
    • This means ElementTree can turn perfectly working documents into ones that can cause compatibility headaches.

ElementTree should just use the default namespace, and only resort to prefixes if the default namespace is already in use.

Workaround

In the above example, pass default_namespace="somens" to ET.tostring(). Note this requires the user to know the namespace URL in advance. If they don't know it in advance they can get it from the root element but ElementTree doesn't make that easy: it requires ugly string parsing on the element name.

CPython versions tested on:

3.11

Operating systems tested on:

Linux

@dechamps dechamps added the type-bug An unexpected behavior, bug, or error label Dec 23, 2023
dechamps added a commit to dechamps/videojitter-sandbox that referenced this issue Dec 23, 2023
This is because of the spurious `ns0:` XML namespace prefix, see
python/cpython#113425.
dechamps added a commit to dechamps/videojitter that referenced this issue Dec 23, 2023
This is because of the spurious `ns0:` XML namespace prefix, see
python/cpython#113425.
@gaogaotiantian
Copy link
Contributor

First of all, I think this should be a feature request, instead of a bug, because it is not WRONG and it does not contradict the documentation.

From a feature request point of view, I like the propsed result, but there are a couple of things to concern.

  1. This is a BREAKING change. Yes, semantically it's still the same, but like you said, semantics are not the only thing to worry about. This could break someone's code. We need an expert to evaluate the benefit vs the cost. This module has behaved like this for a long time.
  2. It's not trivial (from my understanding) because the data we need is lost during parsing (not serializing). As far as I can tell, <ns0:foo xmlns:ns0="somens">a<ns0:bar /></ns0:foo> and <foo xmlns="somens">a<bar /></foo> are parsed to the same ElementTree. So in order to conform to the principle of least surprise, ET.tostring(ET.fromstring("<ns0:foo xmlns:ns0="somens">a<ns0:bar /></ns0:foo>"), encoding="unicode") should be <ns0:foo xmlns:ns0="somens">a<ns0:bar /></ns0:foo> which is not possible without changing the parsing part.

I'm not saying it's impossible (well very few things are really impossible in software world), but we need further discussion (presumably with some core devs involved) in this. I won't be too optimistic about this request because of the reasons I mentioned above. You might be recommended to use some 3rd party libraries to do this kind of work.

Let's see if this can raise anyone's interests to the topic :)

@hexagonrecursion
Copy link
Contributor

hexagonrecursion commented Dec 30, 2023

For example, the SVG viewer in VS Code and in the GitHub file browser get confused if an SVG file uses namespace prefixes. (This is how I stumbled upon this issue)

Based on the very limited information you provided this sounds like you should report this as a bug on their end - they are the ones who failed to correctly implement the Namespaces in XML specification.

@dechamps
Copy link
Author

@hexagonrecursion I agree that it's a bug on their end, but consider the Robustness principle - "be conservative in what you send, be liberal in what you accept". Randomly adding namespace prefixes where none are required is not being "conservative in what you send". Fixing ElementTree to produce XML that is less likely to cause problems, and fixing bugs in consumers, are not mutually exclusive propositions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic-XML type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

4 participants