0

I am having problems generating a XML document using the ElementTree framework in Python 3. I tried registering the namespace before setting up the document. Right now it seems that I can generate a XML document only by adding the namespace to each element like a=Element("{full_namespace_URI}element_name") which seems tedious.

How do I setup the default namespace and can omit putting it in each element?

Any help is appreciated.

I have written a small demo program for Python 3:

    from io import BytesIO                                                                                                                                                
    from xml.etree import ElementTree as ET                                                                                                                               
                                                                                                                                                                          
    ET.register_namespace("", "urn:dslforum-org:service-1-0")                                                                                                             
                                                                                                                                                                          
    """                                                                                                                                                                   
    desired output                                                                                                                                                        
    ==============                                                                                                                                                        
    <?xml version='1.0' encoding='utf-8'?>                                                                                                                                
    <topNode xmlns="urn:dslforum-org:service-1-0"">                                                                                                                       
        <childNode>content</childNode>                                                                                                                                    
    </topNode>                                                                                                                                                            
    """                                                                                                                                                                   
                                                                                                                                                                          
                                                                                                                                                                          
    # build XML document without namespaces                                                                                                                               
    a = ET.Element("topNode")                                                                                                                                             
    b = ET.Element("childNode")                                                                                                                                           
    b.text = "content"                                                                                                                                                    
    a.append(b)                                                                                                                                                           
    tree = ET.ElementTree(a)                                                                                                                                              
                                                                                                                                                                          
    # build XML document with namespaces                                                                                                                                  
    a_ns = ET.Element("{dsl}topNode")                                                                                                                                     
    b_ns = ET.Element("{dsl}childNode")                                                                                                                                   
    b_ns.text = "content"                                                                                                                                                 
    a_ns.append(b_ns)                                                                                                                                                     
    tree_ns = ET.ElementTree(a_ns)                                                                                                                                        
                                                                                                                                                                          
    def print_element_tree(element_tree, comment, default_namespace=None):                                                                                                
        """                                                                                                                                                               
        print element tree with comment to standard out                                                                                                                   
        """                                                                                                                                                               
        with BytesIO() as buf:                                                                                                                                            
            element_tree.write(buf, encoding="utf-8", xml_declaration=True,                                                                                               
                               default_namespace=default_namespace)                                                                                                       
            buf.seek(0)                                                                                                                                                   
            print(comment)                                                                                                                                                
            print(buf.read().decode("utf-8"))                                                                                                                             
                                                                                                                                                                          
    print_element_tree(tree, "Element Tree without XML namespace")                                                                                                        
    print_element_tree(tree_ns, "Element Tree with XML namespace", "dsl")
1

1 Answer 1

2

I believe you are overthinking this.

Registering a default namespace in your code avoids the ns0: aliases.

Registering any namespaces you will use while creating a document allows you to designate the alias used for each namespace.

To achieve your desired output, assign the namespace to your top element:

a = ET.Element("{urn:dslforum-org:service-1-0}topNode")

The preceding ET.register_namespace("", "urn:dslforum-org:service-1-0") will make that the default namespace in the document, assign it to topNode, and not prefix your tag names.

<?xml version='1.0' encoding='utf-8'?>
<topNode xmlns="urn:dslforum-org:service-1-0"><childNode>content</childNode></topNode>

If you remove the register_namespace() call, then you get this monstrosity:

<?xml version='1.0' encoding='utf-8'?>
<ns0:topNode xmlns:ns0="urn:dslforum-org:service-1-0"><childNode>content</childNode></ns0:topNode>
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much, that was exactly the solution I was hoping for. Concise, easy and pythonic. I got confused by the "default_namespace" option in the write method which interferes with the rest. When it is used like you propose, you have to omit the default_namespace option in the write method.
Thank you! It was helpful for me. How it is possible to add the xml version and encoding values?
@BernardoTroncoso When calling element_tree.write() set xml_declaration=True

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.