天道酬勤,学无止境

Python: ignoring namespaces in xml.etree.ElementTree?

How can I tell ElementTree to ignore namespaces in an XML file?

For example, I would prefer to query modelVersion (as in statement 1) rather than {http://maven.apache.org/POM/4.0.0}modelVersion (as in statement 2).

pom="""
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
</project>
"""

from xml.etree import ElementTree
ElementTree.register_namespace("","http://maven.apache.org/POM/4.0.0")
root = ElementTree.fromstring(pom)

print 1,root.findall('modelVersion')
print 2,root.findall('{http://maven.apache.org/POM/4.0.0}modelVersion')

1 []
2 [<Element '{http://maven.apache.org/POM/4.0.0}modelVersion' at 0x1006bff10>]

评论

There appears to be no straight-forward pathway, thus I'd simply wrap the find calls, e.g.

from xml.etree import ElementTree as ET

POM = """
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>
</project>
"""

NSPS = {'foo' : "http://maven.apache.org/POM/4.0.0"}

# sic!
def findall(node, tag):
    return node.findall('foo:' + tag, NSPS) 

root = ET.fromstring(POM)
print(map(ET.tostring, findall(root, 'modelVersion')))

output:

['<ns0:modelVersion xmlns:ns0="http://maven.apache.org/POM/4.0.0">4.0.0</ns0:modelVersion>\n']

Here's what I'm presently doing, which makes me incredibly confident that there's a better way.

$ cat pom.xml |
   tr '\n' ' ' |
   sed 's/<project [^>]*>/<project>/' |
   myprogram |
   sed 's/<project>/<project xmlns="http:\/\/maven.apache.org\/POM\/4.0.0" xmlns:xsi="http:\/\/www.w3.org\/2001\/XMLSchema-instance" xsi:schemaLocation="http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/maven-v4_0_0.xsd">/'

Rather than ignore, another approach would be to remove the namespaces in the tree, so there's no need to 'ignore' because they aren't there - see nonagon's answer to this question (and my extension of that to include namespaces on attributes): Python ElementTree module: How to ignore the namespace of XML files to locate matching element when using the method "find", "findall"

Here's the equivalent solution without using the shell. Basic idea:

  • translate <project junk...> to <project>
  • perform "clean" processing without worrying about the namespace
  • translate <project> back to <project junk...>

with the new code:

pom="""
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
</project>
"""
short_project="""<project>"""
long_project="""<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">"""

import re,sys
from xml.etree import ElementTree

# eliminate namespace specs
pom=re.compile('<project [^>]*>').sub(short_project,pom)

root = ElementTree.fromstring(pom)
ElementTree.dump(root)
print 1,root.findall('modelVersion')
print 2,root.findall('{http://maven.apache.org/POM/4.0.0}modelVersion')
mv=root.findall('modelVersion')

# restore the namespace specs
pom=ElementTree.tostring(root)
pom=re.compile(short_project).sub(long_project,pom)

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • Python ElementTree模块:使用“ find”,“ findall”方法时,如何忽略XML文件的命名空间以找到匹配的元素(Python ElementTree module: How to ignore the namespace of XML files to locate matching element when using the method “find”, “findall”)
    问题 我想使用“ findall”方法在ElementTree模块中找到源xml文件的某些元素。 但是,源xml文件(test.xml)具有名称空间。 我截断一部分xml文件作为示例: <?xml version="1.0" encoding="iso-8859-1"?> <XML_HEADER xmlns="http://www.test.com"> <TYPE>Updates</TYPE> <DATE>9/26/2012 10:30:34 AM</DATE> <COPYRIGHT_NOTICE>All Rights Reserved.</COPYRIGHT_NOTICE> <LICENSE>newlicense.htm</LICENSE> <DEAL_LEVEL> <PAID_OFF>N</PAID_OFF> </DEAL_LEVEL> </XML_HEADER> 示例python代码如下: from xml.etree import ElementTree as ET tree = ET.parse(r"test.xml") el1 = tree.findall("DEAL_LEVEL/PAID_OFF") # Return None el2 = tree.findall("{http://www.test.com}DEAL_LEVEL/{http://www.test
  • Python XPath SyntaxError:谓词无效(Python XPath SyntaxError: invalid predicate)
    问题 我正在尝试解析一个 xml 之类的 <document> <pages> <page> <paragraph>XBV</paragraph> <paragraph>GHF</paragraph> </page> <page> <paragraph>ash</paragraph> <paragraph>lplp</paragraph> </page> </pages> </document> 这是我的代码 import xml.etree.ElementTree as ET tree = ET.parse("../../xml/test.xml") root = tree.getroot() path="./pages/page/paragraph[text()='GHF']" print root.findall(path) 但我收到一个错误 print root.findall(path) File "X:\Anaconda2\lib\xml\etree\ElementTree.py", line 390, in findall return ElementPath.findall(self, path, namespaces) File "X:\Anaconda2\lib\xml\etree\ElementPath.py", line 293, in findall
  • 使用 xml.etree.ElementTree 在 Python 中进行简单的 dom 遍历(Simple dom traversing in Python using xml.etree.ElementTree)
    问题 例如考虑解析一个pom.xml文件: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <parent> <groupId>com.parent</groupId> <artifactId>parent</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent> <modelVersion>2.0.0</modelVersion> <groupId>com.parent.somemodule</groupId> <artifactId>some_module</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>Some Module</name> ... 代码: import xml.etree
  • 在 Python 中解析带有未声明前缀的 XML(Parsing XML with undeclared prefixes in Python)
    问题 我正在尝试使用使用前缀的 Python 解析 XML 数据,但并非每个文件都具有前缀的声明。 示例 XML: <?xml version="1.0" encoding="UTF-8"?> <item subtype="bla"> <thing>Word</thing> <abc:thing2>Another Word</abc:thing2> </item> 我一直在使用 xml.etree.ElementTree 来解析这些文件,但是只要前缀没有正确声明,ElementTree 就会抛出解析错误。 ( unbound prefix ,就在<abc:thing2> )搜索此错误使我找到了建议修复命名空间声明的解决方案。 但是,我无法控制需要使用的 XML,因此修改输入文件不是一个可行的选择。 搜索命名空间解析一般会导致我对以命名空间不可知的方式搜索的许多问题,这不是我所需要的。 我正在寻找某种方法来自动解析这些文件,即使命名空间声明被破坏。 我想过做以下事情: 事先告诉 ElementTree 需要哪些命名空间,因为我知道哪些可以发生。 我找到了register_namespace ,但这似乎不起作用。 在解析之前读入完整的 DTD,看看是否能解决它。 我找不到使用 ElementTree 执行此操作的方法。 告诉 ElementTree 根本不要理会命名空间。
  • 如何使用 python xml.etree.ElementTree 解析 eBay API 响应?(how to use python xml.etree.ElementTree to parse eBay API response?)
    问题 我正在尝试使用 xml.etree.ElementTree 来解析来自 eBay 查找 API findItemsByProduct 的响应。 经过长时间的反复试验,我想出了这个打印一些数据的代码: import urllib from xml.etree import ElementTree as ET appID = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' isbn = '3868731342' namespace = '{http://www.ebay.com/marketplace/search/v1/services}' url = 'http://svcs.ebay.com/services/search/FindingService/v1?' \ + 'OPERATION-NAME=findItemsByProduct' \ + '&SERVICE-VERSION=1.0.0' \ + '&GLOBAL-ID=EBAY-DE' \ + '&SECURITY-APPNAME=' + appID \ + '&RESPONSE-DATA-FORMAT=XML' \ + '&REST-PAYLOAD' \ + '&productId.@type=ISBN&productId=' + isbn root = ET.parse
  • 在 ElementTree 1.2 中抑制命名空间前缀(Suppressing namespace prefixes in ElementTree 1.2)
    问题 在 python 2.7(使用 etree 1.3)中,我可以抑制元素上的 XML 前缀,如下所示: Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) [GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import xml.etree.ElementTree as etree >>> etree.VERSION '1.3.0' >>> something = etree.Element('{http://some.namespace}token') >>> etree.tostring(something) '<ns0:token xmlns:ns0="http://some.namespace" />' >>> etree.register_namespace('', 'http://some.namespace') >>> etree.tostring(something) '<token xmlns="http://some.namespace" />'
  • 如何使用ElementTree输出CDATA(How to output CDATA using ElementTree)
    问题 我发现cElementTree比xml.dom.minidom快30倍,并且正在重写XML编码/解码代码。 但是,我需要输出包含CDATA节的XML,并且似乎没有办法用ElementTree做到这一点。 能做到吗 回答1 经过一些工作,我自己找到了答案。 查看ElementTree.py源代码,我发现对XML注释和预处理指令进行了特殊处理。 他们要做的是为特殊元素类型创建工厂函数,该函数使用特殊(非字符串)标记值将其与常规元素区分开。 def Comment(text=None): element = Element(Comment) element.text = text return element 然后,在实际输出XML的ElementTree的_write函数中,有一种特殊情况的注释处理: if tag is Comment: file.write("<!-- %s -->" % _escape_cdata(node.text, encoding)) 为了支持CDATA节,我创建了一个名为CDATA的工厂函数,扩展了ElementTree类,并更改了_write函数以处理CDATA元素。 如果您想解析带有CDATA部分的XML,然后再次与CDATA部分一起输出,这仍然无济于事,但是它至少允许您以编程方式创建带有CDATA部分的XML。
  • Python ElementTree默认名称空间?(Python ElementTree default namespace?)
    问题 有没有一种方法可以在python ElementTree中定义默认/无前缀的命名空间? 这似乎不起作用... ns = {"":"http://maven.apache.org/POM/4.0.0"} pom = xml.etree.ElementTree.parse("pom.xml") print(pom.findall("version", ns)) 这也不是: ns = {None:"http://maven.apache.org/POM/4.0.0"} pom = xml.etree.ElementTree.parse("pom.xml") print(pom.findall("version", ns)) 可以,但是我必须在每个元素前加上前缀: ns = {"mvn":"http://maven.apache.org/POM/4.0.0"} pom = xml.etree.ElementTree.parse("pom.xml") print(pom.findall("mvn:version", ns)) 在OSX上使用Python 3.5。 编辑:如果答案为“否”,您仍然可以获得赏金:-)。 我只是想要一个花了很多时间使用它的人的明确“否”。 回答1 没有简单的方法可以透明地处理默认名称空间。 正如您已经提到的,为空名称空间分配非空名称是一种常见的解决方案: ns
  • UnicodeDecodeError:“ ascii”编解码器无法解码字节0xc2(UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2)
    问题 我正在用Python创建XML文件,我的XML上有一个字段,用于放置文本文件的内容。 我这样做 f = open ('myText.txt',"r") data = f.read() f.close() root = ET.Element("add") doc = ET.SubElement(root, "doc") field = ET.SubElement(doc, "field") field.set("name", "text") field.text = data tree = ET.ElementTree(root) tree.write("output.xml") 然后我得到了UnicodeDecodeError 。 我已经尝试在脚本上方加上特殊注释# -*- coding: utf-8 -*- ,但仍然出现错误。 我也已经尝试对变量data.encode('utf-8')进行编码,但是仍然出现错误。 我知道这个问题非常普遍,但是我从其他问题中获得的所有解决方案都不适用于我。 更新 追溯:仅在脚本第一行使用特殊注释 Traceback (most recent call last): File "D:\Python\lse\createxml.py", line 151, in <module> tree.write("D:\\python\\lse\\xmls
  • 可以告诉ElementTree保留属性的顺序吗?(Can ElementTree be told to preserve the order of attributes?)
    问题 我使用ElementTree在python中编写了一个相当简单的过滤器,以调整某些xml文件的上下文。 它或多或少地起作用。 但是它重新排序了各种标签的属性,我希望它不要这样做。 有人知道我可以扔出一个开关以使其保持在指定的顺序吗? 上下文 我正在使用一个粒子物理工具,该工具具有基于xml文件的复杂但奇怪的配置系统。 以这种方式设置的许多事物中包括通往各种静态数据文件的路径。 这些路径被硬编码到现有的xml中,没有基于环境变量设置或更改它们的功能,在我们的本地安装中,它们必须位于不同的位置。 这不是灾难,因为我们正在使用的源代码控制和构建控制工具相结合,使我们可以使用本地副本对某些文件进行阴影处理。 但是,即使考虑到数据字段是静态的,xml也不是静态的,所以我编写了用于修复路径的脚本,但是由于属性重新排列,本地版本和主版本之间的差异很难理解,比必要的要难。 这是我第一次带ElementTree旋转(而且只有我的第五个或第六个python项目),所以也许我只是做错了。 为简化起见,代码摘要如下: tree = elementtree.ElementTree.parse(inputfile) i = tree.getiterator() for e in i: e.text = filter(e.text) tree.write(outputfile) 合理还是愚蠢? 相关链接:
  • lxml.etree 和 xml.etree.ElementTree 添加没有前缀的命名空间(ns0、ns1 等)(lxml.etree and xml.etree.ElementTree adding namespaces without prefixes(ns0, ns1, etc.))
    问题 有没有任何解决方案可以添加不带前缀的命名空间(我的意思是这些 ns0、ns1),它们适用于所有 etree 实现,或者每个都有工作解决方案? 现在我有以下解决方案: lxml - 元素的 nsmap 参数 (c)ElementTree (python 2.6+) - 以空字符串作为前缀注册命名空间方法 问题是 python 2.5 中的 (c)ElementTree,我知道有 _namespace_map 属性,但将其设置为空字符串创建无效的 XML,将其设置为 None 添加默认 ns0 等命名空间,是否有任何可行的解决方案? 我猜 Element('foo', {'xmlns': 'http://my_namespace_url.org/my_ns'}) 是个坏主意吗? 感谢帮助 回答1 我刚刚为你工作。 定义你自己的前缀: unique = 'bflmpsvz' my_namespaces = { 'http://www.topografix.com/GPX/1/0' : unique, 'http://www.groundspeak.com/cache/1/0' : 'groundspeak', } xml.etree.ElementTree._namespace_map.update( my_namespaces ) 然后,替换/删除输出上的前缀: def
  • 可以告诉 ElementTree 保留属性的顺序吗?(Can ElementTree be told to preserve the order of attributes?)
    问题 我已经使用 ElementTree 在 python 中编写了一个相当简单的过滤器来处理一些 xml 文件的上下文。 它或多或少地起作用。 但是它重新排序了各种标签的属性,我希望它不要这样做。 有谁知道我可以扔一个开关来让它保持指定的顺序? 上下文 我正在使用一个粒子物理工具,该工具具有基于 xml 文件的复杂但奇怪的有限配置系统。 以这种方式设置的许多内容包括各种静态数据文件的路径。 这些路径被硬编码到现有的 xml 中,并且没有用于根据环境变量设置或更改它们的工具,并且在我们的本地安装中,它们必须位于不同的位置。 这不是灾难,因为我们使用的组合源和构建控制工具允许我们使用本地副本隐藏某些文件。 但即使认为数据字段是静态的,xml 也不是,所以我编写了一个脚本来修复路径,但是本地和主版本之间的属性重新排列差异比必要的更难阅读。 这是我第一次尝试使用 ElementTree(并且只是我的第五个或第六个 Python 项目),所以也许我只是做错了。 为简单起见,代码如下所示: tree = elementtree.ElementTree.parse(inputfile) i = tree.getiterator() for e in i: e.text = filter(e.text) tree.write(outputfile) 合理还是愚蠢? 相关链接: 如何使用
  • python:xml.etree.ElementTree,删除“命名空间”(python: xml.etree.ElementTree, removing “namespaces”)
    问题 我喜欢ElementTree解析xml的方式,特别是Xpath功能。 我从带有嵌套标签的应用程序以xml输出。 我想按名称访问此标签,而不指定名称空间,这可能吗? 例如: root.findall("/molpro/job") 代替: root.findall("{http://www.molpro.net/schema/molpro2006}molpro/{http://www.molpro.net/schema/molpro2006}job") 回答1 至少使用lxml2,可以稍微减少此开销: root.findall("/n:molpro/n:job", namespaces=dict(n="http://www.molpro.net/schema/molpro2006")) 回答2 您可以编写自己的函数来包装讨厌的外观,例如: def my_xpath(doc, ns, xp); num = xp.count('/') new_xp = xp.replace('/', '/{%s}') ns_tup = (ns,) * num doc.findall(new_xp % ns_tup) namespace = 'http://www.molpro.net/schema/molpro2006' my_xpath(root, namespace, '/molpro/job'
  • 在 Python 中创建与 xml.etree.ElementTree.findall() 一起使用的字典时,是否有默认命名空间的键?(Is there a key for the default namespace when creating dictionary for use with xml.etree.ElementTree.findall() in Python?)
    问题
  • Python 模块 xml.etree.ElementTree 自动修改 xml 命名空间键(Python module xml.etree.ElementTree modifies xml namespace keys automatically)
    问题 我注意到 python ElementTree 模块在以下简单示例中更改了 xml 数据: import xml.etree.ElementTree as ET tree = ET.parse("./input.xml") tree.write("./output.xml") 我不希望它改变,因为我已经完成了简单的读写测试,没有任何修改。 然而,结果显示了一个不同的故事,特别是在命名空间索引中(nonage --> ns0 , d3p1 --> ns1 , i --> ns2 ): 输入.xml: <?xml version="1.0" encoding="utf-8"?> <ServerData xmlns:i="http://www.a.org" xmlns="http://schemas.xxx/2004/07/Server.Facades.ImportExport"> <CreationDate>0001-01-01T00:00:00</CreationDate> <Processes> <Processes xmlns:d3p1="http://schemas.datacontract.org/2004/07/Management.Interfaces"> <d3p1:ProtectedProcess> <d3p1:Description>/Applications
  • Python 操作和保存 XML,更改一项属性(Python Manipulate and save XML, change one property)
    问题 我有这个xml: <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <m:request xmlns:m="http://www.datapower.com/schemas/management" domain="XXXXX"> <m:do-action> <FlushDocumentCache> <XMLManager class="XMLManager">default</XMLManager> </FlushDocumentCache> <FlushStylesheetCache> <XMLManager class="XMLManager">default</XMLManager> </FlushStylesheetCache> </m:do-action> </m:request> </SOAP-ENV:Body> <
  • Python XPath SyntaxError: invalid predicate
    i am trying to parse an xml like <document> <pages> <page> <paragraph>XBV</paragraph> <paragraph>GHF</paragraph> </page> <page> <paragraph>ash</paragraph> <paragraph>lplp</paragraph> </page> </pages> </document> and here is my code import xml.etree.ElementTree as ET tree = ET.parse("../../xml/test.xml") root = tree.getroot() path="./pages/page/paragraph[text()='GHF']" print root.findall(path) but i get an error print root.findall(path) File "X:\Anaconda2\lib\xml\etree\ElementTree.py", line 390, in findall return ElementPath.findall(self, path, namespaces) File "X:\Anaconda2\lib\xml\etree
  • 如何使用xml.etree.ElementTree编写XML声明(How to write XML declaration using xml.etree.ElementTree)
    问题 我正在使用ElementTree在Python中生成XML文档,但是在转换为纯文本时, tostring函数不包含XML声明。 from xml.etree.ElementTree import Element, tostring document = Element('outer') node = SubElement(document, 'inner') node.NewValue = 1 print tostring(document) # Outputs "<outer><inner /></outer>" 我需要我的字符串包含以下XML声明: <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 但是,似乎没有任何记录的方式来执行此操作。 是否有合适的方法在ElementTree呈现XML声明? 回答1 我很惊讶地发现ElementTree.tostring()似乎没有办法。 但是,您可以使用ElementTree.ElementTree.write()将XML文档写入伪文件: from io import BytesIO from xml.etree import ElementTree as ET document = ET.Element('outer') node = ET.SubElement
  • How to solve TypeError: cannot serialize float Python Elementtree
    问题 我有一个调试问题。 由于我在这里很新,请原谅可能出现的文字墙。 几个小时后,我终于让elementtree做我想做的事,但我无法输出我的结果,因为 tree.write("output3.xml") 也 print(ET.tostring(root)) 给我 TypeError:无法序列化 0.029999999999999999(float64 类型) 我不知道你们需要什么来帮助我,所有的源代码都很长。 错误信息也是如此。 但这有点容易,所以我把它贴在这里...... 提前注意: 据我所见,Ctrl+FI 在我的数据中没有那个 0.029999999... 我的数据中的所有数字都四舍五入到小数点后两位顺便说一句,四舍五入会改变什么吗? 还是只是为了展示? 我对此感到非常困惑,特别是因为似乎没有可通过谷歌搜索的类似案例,只有几乎但不是完全足够的案例。 -------------------------------------------------- ------------------------- TypeError Traceback (最近一次调用最后一次) in () ----> 1 tree.write("output3.xml ") C:\Anaconda\lib\xml\etree\ElementTree.pyc in write(self, file_or
  • Suppressing namespace prefixes in ElementTree 1.2
    In python 2.7 (with etree 1.3), I can suppress the XML prefixes on elements like this: Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) [GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import xml.etree.ElementTree as etree >>> etree.VERSION '1.3.0' >>> something = etree.Element('{http://some.namespace}token') >>> etree.tostring(something) '<ns0:token xmlns:ns0="http://some.namespace" />' >>> etree.register_namespace('', 'http://some.namespace') >>> etree.tostring(something) '<token xmlns=