从XML-Python中删除ns0、ns1、ns2名称空间

从XML-Python中删除ns0、ns1、ns2名称空间,python,xml,namespaces,lxml,elementtree,Python,Xml,Namespaces,Lxml,Elementtree,我试图使用Python的lxml库用预先确定的名称空间重写XML,但在重写时遇到了一个错误。我还试图在重写xml时修改一个元素值,这似乎是可行的,但它随后会附加ns0、ns1和ns2名称空间来代替它们预先分配的前缀。下面是我正在使用的代码,以及输入XML和得到的输出 import xml.etree.ElementTree at ET import os import lxml import glob path = "C:\\Users\\mdl518\\Desktop\\"

我试图使用Python的lxml库用预先确定的名称空间重写XML,但在重写时遇到了一个错误。我还试图在重写xml时修改一个元素值,这似乎是可行的,但它随后会附加ns0、ns1和ns2名称空间来代替它们预先分配的前缀。下面是我正在使用的代码,以及输入XML和得到的输出

import xml.etree.ElementTree at ET
import os
import lxml
import glob

path = "C:\\Users\\mdl518\\Desktop\\"  # contains the input XML

def tag_rename():

for filename in glob.glob(os.path.join(path, "*.xml")):
    with open(filename, 'r', encoding='utf-8'):
        my_namespaces = dict([node for _, node in ET.iterparse(filename, events=['start-ns'])])
        ET.register_namespace=my_namespaces
        tree=ET.parse(filename)
        root=tree.getroot()
    
        for elem in root.findall('.//{http://standards.iso.org/iso/19115/-3/cit/1.0}nameIdentifier'):
            elem.tag = "{http://standards.iso.org/iso/19115/-3/cit/1.0}Test"

            with open(os.path.join(path, "test_rewrite.xml"), "wb") as b:
                tree.write(b)
tag_rename()
输入XML:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="template.xsl"?>
<nas:Metadata xmlns:cit="http://standards.iso.org/iso/19115/-3/cit/1.0"
xmlns:gco="http://standards.iso.org/iso/19115/-3/gco/1.0"
xmlns:lan="http://standards.iso.org/iso/19115/-3/lan/1.0">
 <gco:metadataIdentifier>
    <lan:textIdentifier>
          <cit:nameIdentifer>
         </cit:nameIdentifier>
   </lan:textIdentifier>
   </gco:metadataIdentifier>        
 </nas:Metadata>

输出XML:

<ns0:Metadata xmlns:ns3="http://standards.iso.org/iso/19115/-3/cit/1.0"
xmlns:ns1="http://standards.iso.org/iso/19115/-3/gco/1.0"
xmlns:ns2="http://standards.iso.org/iso/19115/-3/lan/1.0">
 <ns1:metadataIdentifier>
    <ns2:textIdentifier>
          <ns3:Test>
         </ns3:Test>
   </ns2:textIdentifier>
   </ns1:metadataIdentifier>        
 </ns0:Metadata>


我尝试了多种使用lxml和eTree的方法来保留名称空间的原始前缀,但仍然无法解决这个问题,非常感谢您的帮助

我不得不对您的xml示例进行一些更改,包括发明了一个带有假的
nas
命名空间声明的
标记。我还对脚本进行了一些修剪,以处理单个文件。在那之后,它只是切换到
lxml
的一个例子,它比
ElementTree
具有更好的名称空间支持,并向write添加一个参数

test.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="template.xsl"?>
<root xmlns:nas="http://this/is/not/right">
<nas:Metadata xmlns:cit="http://standards.iso.org/iso/19115/-3/cit/1.0"
xmlns:gco="http://standards.iso.org/iso/19115/-3/gco/1.0"
xmlns:lan="http://standards.iso.org/iso/19115/-3/lan/1.0">
 <gco:metadataIdentifier>
    <lan:textIdentifier>
          <cit:nameIdentifier>
         </cit:nameIdentifier>
   </lan:textIdentifier>
   </gco:metadataIdentifier>        
 </nas:Metadata>
 </root>
output.xml

<?xml version='1.0' encoding='ASCII'?>
<?xml-stylesheet type="text/xsl" href="template.xsl"?><root xmlns:nas="http://this/is/not/right">
<nas:Metadata xmlns:cit="http://standards.iso.org/iso/19115/-3/cit/1.0" xmlns:gco="http://standards.iso.org/iso/19115/-3/gco/1.0" xmlns:lan="http://standards.iso.org/iso/19115/-3/lan/1.0">
 <gco:metadataIdentifier>
    <lan:textIdentifier>
          <cit:Test>
         </cit:Test>
   </lan:textIdentifier>
   </gco:metadataIdentifier>        
 </nas:Metadata>


为了确保我理解,您希望输出为
cit:
gco:
lan:
.tdelaney-正确,我希望在重写XML时保留cit:、gco:、和lan:名称空间。我正在Spyder环境中运行该脚本,它似乎曾经运行过一次,但没有更改任何内容并重新运行,我现在不断地收到ns0、ns1、ns2错误。这很令人沮丧,但任何帮助都是非常感谢的!缩进不太正确,的
应该在
def
中,我认为第二个
要写的
应该被删除。还有点吹毛求疵。编写易于运行的测试。我必须重写代码,以避免扫描目录并打开名为test.py的文件。尝试使脚本尽可能接近可运行状态。tdelaney-你是对的,我实际上没有在脚本的复制/粘贴中捕获缩进错误,但是for/with语句在我的Spyder环境中的def下。但是,代码不扫描目录的主要重写是什么?我非常感谢您的帮助/见解!:)nit pick2-xml也不太正确<代码>nas:
未定义。cit:nameIdentifer拼写错误。太棒了!!这就成功了,是的,我对ElementTree也有了自己的“乐趣”,所以lxml看起来更实用。您的编辑工作很好,将节省我的头痛,我会高兴地承认您的解决方案是正确的答案-再次感谢!ElementTree出现在处理xml的良好标准方法出现之前
lxml
依赖于libxml2和libxslt,这在历史上很难跨平台获得。这已经基本解决了,所以对我来说,ElementTree不再需要了。再见,谢谢你的鱼。还可以直接绑定到libxml2和libxslt,这可能有点暗,但对于xml文档的批量处理来说可能更快。
<?xml version='1.0' encoding='ASCII'?>
<?xml-stylesheet type="text/xsl" href="template.xsl"?><root xmlns:nas="http://this/is/not/right">
<nas:Metadata xmlns:cit="http://standards.iso.org/iso/19115/-3/cit/1.0" xmlns:gco="http://standards.iso.org/iso/19115/-3/gco/1.0" xmlns:lan="http://standards.iso.org/iso/19115/-3/lan/1.0">
 <gco:metadataIdentifier>
    <lan:textIdentifier>
          <cit:Test>
         </cit:Test>
   </lan:textIdentifier>
   </gco:metadataIdentifier>        
 </nas:Metadata>