Python处理XML时NS1命名空间前缀残留问题求助
Hey Lucas, let’s fix that pesky NS1 namespace prefix that’s sticking around even after you removed NS0 with ET.register_namespace. I’ve dealt with this exact headache when working with NFe XMLs (they’re notoriously finicky with namespaces), so here’s how to get rid of it:
Step 1: Identify what NS1 actually maps to
ElementTree assigns NS0, NS1, etc. to any namespaces you haven’t explicitly registered. First, let’s find out which URI is tied to NS1. Run this quick snippet on your original XML:
import xml.etree.ElementTree as ET tree = ET.parse("your_input_nfe.xml") root = tree.getroot() print(root.nsmap)
This will print a dictionary of all namespaces in your XML. Look for an entry like 'ns1': 'http://some-namespace-uri.com' — that’s the URI we need to handle. For NFe files, this is often a secondary namespace like http://www.portalfiscal.inf.br/nfe/xsd or a related schema URI.
Step 2: Register all required namespaces
You already registered the default NFe namespace, but you need to register the NS1 URI too. If the URI should use a specific prefix (like xsd for schema-related tags), register it with that prefix. If it’s supposed to be part of the default namespace (unlikely, since default can only have one), double-check your XML structure.
Example registration:
# Default NFe namespace (you already have this) ET.register_namespace('', "http://www.portalfiscal.inf.br/nfe") # Register the NS1 namespace with a meaningful prefix (adjust the URI to match your root.nsmap output) ET.register_namespace('xsd', "http://www.portalfiscal.inf.br/nfe/xsd")
If you don’t want a prefix for this namespace (and it’s allowed by your XML schema), you can’t set two defaults — so you’ll need to ensure all elements using this URI are properly qualified with the namespace when you create/modify them.
Step 3: Fix element creation/modification
The most common reason NS1 pops up is when you create new elements without specifying their correct namespace. Instead of creating elements like ET.Element("new_tag"), you need to qualify them with the namespace URI.
For example:
# Get the namespace URIs you need ns_default = "http://www.portalfiscal.inf.br/nfe" ns_xsd = "http://www.portalfiscal.inf.br/nfe/xsd" # Create an element in the default namespace new_default_elem = ET.Element(f"{{{ns_default}}}new_tag") root.append(new_default_elem) # Create an element in the previously NS1 namespace new_xsd_elem = ET.Element(f"{{{ns_xsd}}}schema_tag") root.append(new_xsd_elem)
This tells ElementTree exactly which namespace each element belongs to, so it won’t assign random NS1 prefixes.
Step 4: Write the XML correctly
When saving your modified XML, use these parameters to avoid unexpected issues:
tree.write("output_nfe.xml", encoding="utf-8", xml_declaration=True)
Avoid adding the default_namespace parameter here — since you’ve already registered the default namespace, ElementTree will handle it properly.
If NS1 still won’t go away...
Check for elements in your XML that might have leftover namespace declarations. Sometimes, old xmlns:ns1="..." attributes stick around in child elements. You can clean these up by iterating through all elements and removing any unwanted namespace attributes:
for elem in root.iter(): # Remove any ns1 declarations (adjust the attribute name to match your case) if 'xmlns:ns1' in elem.attrib: del elem.attrib['xmlns:ns1']
That should do it! NFe XMLs are strict with namespaces, but once you register all URIs and qualify your elements correctly, those random NS prefixes will disappear.
内容的提问来源于stack exchange,提问作者Lucas Monteiro

