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

标签 python xml namespaces lxml elementtree

我正在尝试使用 Python 的 lxml 库重写具有预定 namespace 的 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 示例进行一些更改,包括发明 <root>标签持有假货nas命名空间声明。我还对脚本进行了一些修改以处理单个文件。之后,只需切换到lxml即可。它比 ElementTree 具有更好的命名空间支持并向写入添加参数。

测试.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>

测试.py

import lxml.etree as ET
import os
import lxml
import glob

def tag_rename(filename):
    with open(filename, 'r', encoding='utf-8'):
        my_namespaces = dict([node 
            for _, node in ET.iterparse(filename, events=['start-ns'])])
        for item in my_namespaces.items():
            print(item)
        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("output.xml", "wb") as b:
            tree.write(b,xml_declaration=True)

tag_rename("test.xml")

输出.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>

关于python - 从 XML 中删除 ns0、ns1、ns2 命名空间 - Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62544576/

相关文章:

python - 在模式中匹配 RegEx 模式

python - 如何从 Keras 嵌入层获取词向量

java - 将 java 对象可靠地存储在文件中的最少代码

c# - 如何在 XML soap 消息中发送 "Raw XML"; C#、.Net 网络服务

c++ - 从 namespace 中提取单个名称

javascript - 关于 javascript 命名空间的问题

c# - 为什么System.ServiceModel.Dispatcher需要全限定才能编译

Python - 如果包含列表中元组的元素,则仅打印行

java - 开发可扩展的聊天系统

python - ElementTree 是否生成自己的 nsmap,而 lxml.etree 则不生成?