- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我有一个以下格式的 XML 文件
<?xml version="1.0" encoding="utf-8"?>
<foo>
<bar>
<bat>1</bat>
</bar>
<a>
<b xmlns="urn:schemas-microsoft-com:asm.v1">
<c>1</c>
</b>
</a>
</foo>
我想将 bat 的值更改为“2”并将文件更改为:
<?xml version="1.0" encoding="utf-8"?>
<foo>
<bar>
<bat>2</bat>
</bar>
<a>
<b xmlns="urn:schemas-microsoft-com:asm.v1">
<c>1</c>
</b>
</a>
</foo>
我通过这样做打开这个文件
tree = ET.parse(filePath)
root = tree.getroot()
然后我将 bat 的值更改为“2”并像这样保存文件:
tree.write(filePath, "utf-8", True, None, "xml")
bat 的值成功更改为 2,但 XML 文件现在看起来像这样。
<?xml version="1.0" encoding="utf-8"?>
<foo xmlns:ns0="urn:schemas-microsoft-com:asm.v1">
<bar>
<bat>2</bat>
</bar>
<a>
<ns0:b>
<ns0:c>1</ns0:c>
</ns0:b>
</a>
</foo>
为了解决名为 ns0 的命名空间的问题,我在解析文档之前执行了以下操作
ET.register_namespace('', "urn:schemas-microsoft-com:asm.v1")
这摆脱了 ns0 命名空间,但 xml 文件现在看起来像这样
<?xml version="1.0" encoding="utf-8"?>
<foo xmlns="urn:schemas-microsoft-com:asm.v1">
<bar>
<bat>2</bat>
</bar>
<a>
<b>
<c>1</c>
</b>
</a>
</foo>
我该怎么做才能得到我需要的输出?
最佳答案
据我所知,没有办法通过 xml.etree.ElementTree
方法来实现您的目标。通过深入研究 xml.etree
源代码和 xml
规范,我发现库的行为并没有错,也没有不合理。无论如何,它不允许您正在寻找的输出。
要使用该库实现您的目标,您必须自定义渲染行为。为了最好地满足您的需求,我编写了以下 render
函数。
from xml.etree import ElementTree as ET
from re import findall, sub
def render(root, buffer='', namespaces=None, level=0, indent_size=2, encoding='utf-8'):
buffer += f'<?xml version="1.0" encoding="{encoding}" ?>\n' if not level else ''
root = root.getroot() if isinstance(root, ET.ElementTree) else root
_, namespaces = ET._namespaces(root) if not level else (None, namespaces)
for element in root.iter():
indent = ' ' * indent_size * level
tag = sub(r'({[^}]+}\s*)*', '', element.tag)
buffer += f'{indent}<{tag}'
for ns in findall(r'{[^}]+}', element.tag):
ns_key = ns[1:-1]
if ns_key not in namespaces: continue
buffer += ' xmlns' + (f':{namespaces[ns_key]}' if namespaces[ns_key] != '' else '') + f'="{ns_key}"'
del namespaces[ns_key]
for k, v in element.attrib.items():
buffer += f' {k}="{v}"'
buffer += '>' + element.text.strip() if element.text else '>'
children = list(element)
for child in children:
sep = '\n' if buffer[-1] != '\n' else ''
buffer += sep + render(child, level=level+1, indent_size=indent_size, namespaces=namespaces)
buffer += f'{indent}</{tag}>\n' if 0 != len(children) else f'</{tag}>\n'
return buffer
通过向上述 render()
函数提供您的 xml
输入数据,如下所示:
data =\
'''<?xml version="1.0" encoding="utf-8"?>
<foo>
<bar>
<bat>1</bat>
</bar>
<a>
<b xmlns="urn:schemas-microsoft-com:asm.v1">
<c>1</c>
</b>
</a>
</foo>'''
root = ET.ElementTree(ET.fromstring(data))
ET.register_namespace('', "urn:schemas-microsoft-com:asm.v1")
print(render(root))
它打印出您正在寻找的输出:
<?xml version="1.0" encoding="utf-8" ?>
<foo>
<bar>
<bat>1</bat>
</bar>
<a>
<b xmlns="urn:schemas-microsoft-com:asm.v1">
<c>1</c>
</b>
</a>
</foo>
关于python - 使用 ElementTree 和 Python 覆盖 XML 文件时保留现有命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38663191/
我正在尝试从字符串构建ElementTree。当我执行以下操作时(如 Python ElementTree: Parsing a string and getting ElementTree inst
我正在使用 elementtree.ElementTree.iterparse 来解析大型 (371 MB) xml 文件。 我的代码基本上是这样的: outf = open('out.txt', '
有没有办法在 elementtree.ElementTree 中忽略标记名称中的 XML 命名空间? 我尝试打印所有 technicalContact 标签: for item in root.get
我使用 xml.etree.elementtree.Element 创建了一个 XML 文档,并想使用 ElementTree.write() 函数打印它但是出来的声明标签是 虽然我需要用双引号引起
这个问题已经有答案了: What is the best way to remove accents (normalize) in a Python unicode string? (14 个回答)
我想为此处元素国家/地区新加坡旁边的元素创建子元素。 假设我的 test.xml 文件如下所示 2008 141100
我正在使用ElementTree加载一系列 XML 文件并解析它们。解析文件时,我将从其中获取一些数据(标题和文本段落)。然后我需要获取一些存储在 XML 中的文件名。它们包含在名为 ContentI
我必须将多个 XML 文件合并为一个。此外,新文件的结构也不同。这是我的“旧”结构: 1
我正在解析一个 xml 文件:http://pastebin.com/fw151jQN我希望在副本中读取它的大部分内容并将其写入一个新文件,其中一些已修改,很多未修改,还有很多被忽略。作为初始阶段,我
这是 XML: TARGET_NAME_1 5 a string goes here TARGET_NA
from lxml import etree from xml.etree.ElementTree import Element, SubElement, dump listing = Element
当涉及到模块/库时,为了可读性,我喜欢在 python 中使用完整的命名空间。我想知道为什么这对 xml 库不起作用。我认为 import xml 还将导入 etree 和命名空间中的所有其他内容。至
这里是 Python 菜鸟。想知道删除所有 updated 属性值为 true 的“profile”标签的最干净、最好的方法是什么。 我已经尝试了下面的代码,但它抛出了:SyntaxError("ca
尝试从 xml 文档中删除元素时出现以下错误。“ValueError: list.remove(x): x 不在列表中”这是代码,错误发生在删除的行上。 import xml.etree.Elemen
所以我必须编写一个“重复检查器”来比较两个 XML,看看它们是否相同(包含相同的数据)。现在因为它们来自同一个类并且是从 XSD 结构中生成的,所以内部元素的顺序很可能是相同的。 我能想到的进行重复检
我有一个 XML 文档,我正在使用 ElementTree 阅读和附加该文档。这有多个命名空间声明。据我所知,ElementTree 只允许声明一个全局命名空间: ET.register_namesp
从这里开始: stuff
我是 ElementTree 的新手。我正在尝试获取 来自 XML 响应的值。 以下代码对我不起作用。如何提取 中的值?我不确定号码在哪里 53是从这里来的。 ... r = req
以下代码: import xml.etree.ElementTree as ET xml = '''\ ''' root = ET.fromstring(xml)
我无法控制我获得的 XML 的质量。在某些情况下是: ... 在其他方面我得到: ... 我想我也应该处理 ... 整个架构都是相同的,我只需要一个解析器来处理它。我该如何处理所有这些
我是一名优秀的程序员,十分优秀!