Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:忽略xml.etree.ElementTree中的名称空间?_Python_Xml_Elementtree - Fatal编程技术网

Python:忽略xml.etree.ElementTree中的名称空间?

Python:忽略xml.etree.ElementTree中的名称空间?,python,xml,elementtree,Python,Xml,Elementtree,如何让ElementTree忽略XML文件中的名称空间 例如,我更喜欢查询modelVersion(如语句1所示),而不是{http://maven.apache.org/POM/4.0.0}模型版本(如报表2所示) pom=”“” 4.0.0 """ 从xml.etree导入元素树 ElementTree.register_命名空间(“,”http://maven.apache.org/POM/4.0.0") root=ElementTree.fromstring(pom) 打印1,root.

如何让ElementTree忽略XML文件中的名称空间

例如,我更喜欢查询
modelVersion
(如语句1所示),而不是
{http://maven.apache.org/POM/4.0.0}模型版本
(如报表2所示)

pom=”“”
4.0.0
"""
从xml.etree导入元素树
ElementTree.register_命名空间(“,”http://maven.apache.org/POM/4.0.0")
root=ElementTree.fromstring(pom)
打印1,root.findall('modelVersion')
打印2,root.findall('{http://maven.apache.org/POM/4.0.0}模型版本')
1 []
2 []

似乎没有直接的路径,因此我只需包装find调用,例如

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')))
从xml.etree导入ElementTree作为ET
POM=”“”
4.0.0
"""
NSPS={'foo':“http://maven.apache.org/POM/4.0.0"}
#碳化硅!
def findall(节点、标记):
return node.findall('foo:'+标记,NSPS)
root=ET.fromstring(POM)
打印(映射(ET.tostring,findall(root,'modelVersion'))
输出:

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

以下是我目前正在做的事情,这让我难以置信地相信有更好的方法

$ 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">/'
$cat pom.xml|
tr'\n''|
sed's/]*>/'|
我的计划|
sed's//'

另一种方法是删除树中的名称空间,而不是忽略,因此不需要“忽略”,因为它们不在树中-请参阅nonagon对这个问题的回答(以及我对该问题的扩展,以包括属性上的名称空间):

以下是不使用shell的等效解决方案。基本思想:

  • 翻译成
  • 执行“干净”处理,而不必担心名称空间
  • 翻译回
使用新代码:

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)
pom=”“”
4.0.0
"""
短项目=“”
长项目=“”
输入re,sys
从xml.etree导入元素树
#消除命名空间规范
pom=re.compile(']*>').sub(short_项目,pom)
root=ElementTree.fromstring(pom)
ElementTree.dump(根目录)
打印1,root.findall('modelVersion')
打印2,root.findall('{http://maven.apache.org/POM/4.0.0}模型版本')
mv=root.findall('modelVersion')
#恢复命名空间规范
pom=ElementTree.tostring(根)
pom=re.compile(短项目).sub(长项目,pom)

AFAIK没有一种简单干净的方法可以做到这一点,特别是当您可能要处理多个名称空间时。这似乎是一个重复的问题,但如果你说这些方法不适合你,我就不会使用我的dupehammer(在我看来,它们有点像肮脏的黑客)。此外,但它不是标准库的一部分。遗憾的是,我将此发送给无法安装lxml的人。我希望有一天标准图书馆能将其纳入其中。我发布了我目前的解决方案,这让我非常难过,因为有一次我告诉妈妈我是一名专业程序员-/您可以在python脚本中修补xml字符串,或者创建一个虚拟名称空间和一个包装函数(请参见下面的回答),而不是在管道中使用它。我喜欢在管道中修复它,因为这样我的实际程序就整洁了。如果将来我可以切换到一个更好的xml包,我就可以把这些东西放到包装器中了。好吧,如果你已经对你的管道很满意的话,那么我们到底在谈论什么:)?哈哈,好问题!我希望得到一个类似“YouDummy,这里是如何关闭名称空间wierdness”的答案,但如果没有这个答案,我只希望找到最不坏的选择。对于我来说,这就是保持python代码干净,并在过滤步骤中隐藏可怕的代码。尽管我正努力想弄清楚如何向我的下游peeps交付lxml解决方案!!但是再一次—如果您希望它现在尽可能干净,并且在将来替换导入的xml模块时尽可能保持不变,那么创建一个如我所画的自适应层,我的答案是最自然的,如果不是唯一的方法。最好是只使用xml模块,但不以任何方式继承它,因为在后一种情况下,您将围绕待替换接口构建应用程序,而在第一种情况下,您本身将填充一个为您的应用程序定制的不变接口。
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)