0

I am trying to edit a xml file. I am using the xml.etree library.

My xml

<ext:UBLExtensions>
    <ext:UBLExtension>
        <ext:ExtensionContent>
        </ext:ExtensionContent>
    </ext:UBLExtension>
</ext:UBLExtensions>

my python code

import xml.etree.ElementTree as gfg

tree = gfg.parse('file_name.xml')
root = tree.getroot()
tree.write("file_name.xml")

i haven't change anything but my xml become this.

<ns1:UBLExtensions>
    <ns1:UBLExtension>
        <ns1:ExtensionContent>
        </ns1:ExtensionContent>
    </ns1:UBLExtension>
</ns1:UBLExtensions>

why my header is change ? How can i avoid this ?

2
  • Your XML is giving ParseError. Please use at the beginning: <?xml version="1.0"?> <abc:data xmlns:abc="your namespace"> . Commented Sep 23, 2022 at 14:35
  • 1
    Perhaps you can use lxml instead of ElementTree? lxml does not change existing namespace prefixes. Commented Sep 23, 2022 at 15:11

1 Answer 1

1

The two documents you've posted are identical, as long as the namespace prefix maps to the same namespace. When you have something like this:

<document xmlns:doc="http://example.com/document/v1.0">
  <doc:title>An example</title>
</document>

Then that <doc:title> element means <title> in the http://example.com/document/v1.0` namespace". When you parse the document, your XML parser doesn't particularly care about the prefix, and it will generate a new prefix when writing out the document...

...unless you configure an explicit prefix mapping, which we can do with the register_namespace method. For example:

import xml.etree.ElementTree as etree

etree.register_namespace("ext", "http://example.com/extensions")

tree = etree.parse("data.xml")
tree.write("out.xml")

If data.xml contains:

<example xmlns:ext="http://example.com/extensions">
  <ext:UBLExtensions>
    <ext:UBLExtension>
      <ext:ExtensionContent>
      </ext:ExtensionContent>
    </ext:UBLExtension>
  </ext:UBLExtensions>
</example>

Then the above code will output:

<example xmlns:ext="http://example.com/extensions">
  <ext:UBLExtensions>
    <ext:UBLExtension>
      <ext:ExtensionContent>
      </ext:ExtensionContent>
    </ext:UBLExtension>
  </ext:UBLExtensions>
</example>

Without the call to etree.register_namespace; the output looks like:

<example xmlns:ns0="http://example.com/extensions">
  <ns0:UBLExtensions>
    <ns0:UBLExtension>
      <ns0:ExtensionContent>
      </ns0:ExtensionContent>
    </ns0:UBLExtension>
  </ns0:UBLExtensions>
</example>

It's the same document, and the elements are all still in the same namespace; we're just using a different prefix as the short name of the namespace.

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you very much. This is a great answer. Quick question: \n İf i have multiple namespaces inside of my xml, can i set them too ?
Yes, you can make multiple calls to register_namespace, and it looks like the write method takes a default_namespace parameter.
I'm using these works for e-billing notification to the government and I wanted to do the same with the namespaces in the sample xml I have. But I guess it doesn't matter what the namespaces are. This is purely done to make the xml work properly. It doesn't need to be a standard. That's how I got it, do you agree?
That is technically true (well, it doesn't matter what the namespace prefixes are. The namespaces absolutely matter), and if the XML is solely for machine consumption it's fine. But if the XML is going to be read by people, it makes sense to use the expected namespace prefixes...and since it turns out to be quite easy, you might as well just do it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.