Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.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/9/visual-studio/8.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:ElementTree,获取元素的名称空间字符串_Python_Elementtree - Fatal编程技术网

Python:ElementTree,获取元素的名称空间字符串

Python:ElementTree,获取元素的名称空间字符串,python,elementtree,Python,Elementtree,此XML文件名为example.XML: <?xml version="1.0"?> <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.xs

此XML文件名为
example.XML

<?xml version="1.0"?>
<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>14.0.0</modelVersion>
  <groupId>.com.foobar.flubber</groupId>
  <artifactId>uberportalconf</artifactId>
  <version>13-SNAPSHOT</version>
  <packaging>pom</packaging>
  <name>Environment for UberPortalConf</name>
  <description>This is the description</description>    
  <properties>
      <birduberportal.version>11</birduberportal.version>
      <promotiondevice.version>9</promotiondevice.version>
      <foobarportal.version>6</foobarportal.version>
      <eventuberdevice.version>2</eventuberdevice.version>
  </properties>
  <!-- A lot more here, but as it is irrelevant for the problem I have removed it -->
</project>

我还没有找到一种方法,可以调用该方法仅从
元素
获取名称空间,而不用解析元素的
str(一个元素)
。似乎有更好的方法。

我不确定使用
xml.etree
是否可以做到这一点,但下面是使用
lxml.etree
的方法:

>>> from lxml import etree
>>> tree = etree.parse('example.xml')
>>> tree.xpath('namespace-uri(.)')
'http://maven.apache.org/POM/4.0.0'

我认为更容易查看以下属性:

>>> root.attrib
{'{http://www.w3.org/2001/XMLSchema-instance}schemaLocation':
   'http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd'}

名称空间应位于“实际”标记的正前方:


要了解有关名称空间的更多信息,请查看。

这是一项完美的任务


不使用正则表达式:

>>> root
<Element '{http://www.google.com/schemas/sitemap/0.84}urlset' at 0x2f7cc10>

>>> root.tag.split('}')[0].strip('{')
'http://www.google.com/schemas/sitemap/0.84'
>>根目录
>>>root.tag.split('}')[0]。strip('{')
'http://www.google.com/schemas/sitemap/0.84'

库的
lxml.xtree
元素有一个名为
nsmap
的字典,它显示了当前标记范围中使用的所有命名空间

>>> item = tree.getroot().iter().next()
>>> item.nsmap
{'md': 'urn:oasis:names:tc:SAML:2.0:metadata'}
简单的回答是:

ElementTree._namspace_map[ElementTree._namspace_map.values().index('')]
但前提是你一直在打电话

ElementTree.register_namespace(prefix,uri)
对每个事件的响应==“开始ns”在遍历

ET.iterparse(...) 
你注册了“启动ns”

在回答“默认名称空间是什么?”问题时,有必要澄清两点:

(1) XML规范指出,默认名称空间在整个树中不一定是全局的,而是可以在根目录下的任何元素处重新声明默认名称空间,并向下继承,直到满足另一个默认名称空间重新声明

(2) ElementTree模块可以(事实上)处理类似XML的文档,这些文档没有根默认名称空间,-if-它们在文档中的任何地方都没有名称空间使用。(*可能有不太严格的条件,例如,即“if”而不一定是“iff”)

它可能也值得考虑“你想要什么?”认为XML文件在语义上是等价的,但在语法上是非常不同的。例如,以下三个文件在语义上是等价的,但是A.xml有一个默认的命名空间声明,B.xml有三个,而C.xml没有。

A.xml:
<a xlmns="http://A" xlmns:nsB0="http://B0" xlmns:nsB1="http://B1">
     <nsB0:b/>
     <nsB1:b/>
</a>

B.xml:
<a xlmns="http://A">
     <b xlmns="http://B0"/>
     <b xlmns="http://B1"/>
</a>

C.xml:
<{http://A}a>
     <{http://B0}b/>
     <{http://B1}b/>
</a>
A.xml:

结合上面的一些答案,我认为最短的代码是

theroot = tree.getroot()
theroot.attrib[theroot.keys()[0]]

这是我在ElementTree 3.9+上的解决方案

def get_element_namespaces(filename, element):
    namespace = []
    for key, value in ET.iterparse(filename, events=['start', 'start-ns']):
        print(key, value)
        if key == 'start-ns':
            namespace.append(value)
        else:
            if ET.tostring(element) == ET.tostring(value):
                return namespace
            namespace = []
    return namespaces
这将返回[prefix:URL]元组数组,如下所示:

[('android', 'http://schemas.android.com/apk/res/android'), ('tools', 'http://schemas.android.com/tools')]

我在Windows中使用Python 2.7.2获得了
未解析导入:etree
xpath
在使用
xml.etree
时不能作为方法使用,如果我使用
find()
(支持xpath表达式)则
名称空间-uri(.)“
语句仍然不起作用。这正是我所寻找的,这是我见过的最好的解决方案。我通常使用xmlstarlet,但现在可以切换。对于
lxml
获取名称空间的更简单方法是
tree.getroot().nsmap
@Jona:我假设使用
None
是一种处理默认名称空间的方法,即声明为不带前缀的名称空间。当然比解析
str(the_元素)更容易
。但我想解析
元素.tag更容易一些。因为我只对名称空间感兴趣。你认为呢?我认为@RikPoggi的答案似乎是最好的(事实上,我投了更高的票)。事实上,获得名称空间应该和
重新搜索('\{(.*\}),元素.tag.group(1)一样简单
。根据我的回答,您似乎可以使用
元素.attrib.values()[0].split()[0]
,但事实上,它看起来并不那么简单,也不能保证将来不会获得任何其他属性。你知道在这种情况下如何使用find方法吗?它在这里不起作用……在与这个问题斗争了一段时间后,这是我找到的最佳解决方案。我不敢相信API没有让你提出问题的方法同时,它在执行“rootElement.keys()时不返回属性“xmlns”“。当然有一个很好的理由,但我现在找不到它。在常规exp之前添加
r
请使这个答案完美。@Jiu非常感谢你。我不敢相信我错过了。要获得没有大括号的名称空间,请包括:re.match(r'\{(.*}',element.tag)。组(1)一个类似的答案
root.tag[1:root.tag.index('}])”
这个答案是最简单的。谢谢这是不准确的,因为xmlns可能不是根的第一个属性。事实上,我目前正在尝试解析一个TCX文件,而xmlns根本没有显示为根的属性。您提供的链接已失效,您可能需要对其进行编辑,以指向此信息的其他源。
theroot = tree.getroot()
theroot.attrib[theroot.keys()[0]]
def get_element_namespaces(filename, element):
    namespace = []
    for key, value in ET.iterparse(filename, events=['start', 'start-ns']):
        print(key, value)
        if key == 'start-ns':
            namespace.append(value)
        else:
            if ET.tostring(element) == ET.tostring(value):
                return namespace
            namespace = []
    return namespaces
[('android', 'http://schemas.android.com/apk/res/android'), ('tools', 'http://schemas.android.com/tools')]