【问题标题】:get the namespaces from xml with python ElementTree使用 python ElementTree 从 xml 获取命名空间
【发布时间】:2017-07-08 07:53:01
【问题描述】:

我使用带有 lib ElementTree 的 python 2.7。

我不能使用 lxml 库。

我需要在字符串namespace_string 中获取命名空间。为了填充我的命名空间字典。

我的 xml:

<?xml version="1.0" encoding="UTF-8"?>
<AX_Bestandsdatenauszug
    xmlns="http://www.adv-online.de/namespaces/adv/gid/6.0"
    xmlns:adv="http://www.adv-online.de/namespaces/adv/gid/6.0"
    xmlns:gco="http://www.isotc211.org/2005/gco"
    xmlns:gmd="http://www.isotc211.org/2005/gmd"
    xmlns:gml="http://www.opengis.net/gml/3.2"
    xmlns:ows="http://www.opengis.net/ows"
    xmlns:wfs="http://www.adv-online.de/namespaces/adv/gid/wfs"
    xmlns:wfsext="http://www.adv-online.de/namespaces/adv/gid/wfsext"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ogc="http://www.adv-online.de/namespaces/adv/gid/ogc"
    xsi:schemaLocation="http://www.adv-online.de/namespaces/adv/gid/6.0 NAS-Operationen.xsd">

    <enthaelt>
            <gml:featureMember>
            <xmlstuff>....a lot of xml stuff....</xmlstuff>
            </gml:featureMember>
    </enthaelt>
</AX_Bestandsdatenauszug>

代码:

import clr
import sys

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
sys.path.append("C:\Program Files (x86)\IronPython 2.7\Lib")
import xml.etree.ElementTree as ET
from io import StringIO


xml="file.xml"

tree = ET.parse(xml)
root = tree.getroot()


my_schema = "namespace_string"

my_namespaces = dict([node for _, node in ET.iterparse(StringIO(my_schema), events=['start-ns'])])

字典的代码来自这个答案:https://stackoverflow.com/a/37409050/7317684

我尝试了namespace_string=root.tag,但这只让我 ="{http://www.adv-online.de/namespaces/adv/gid/6.0}AX_Bestandsdatenauszug"

只找到lxml解决方案:(

任何帮助都会很棒!

【问题讨论】:

    标签: xml python-2.7 dictionary elementtree


    【解决方案1】:

    创建包含所有已声明名称空间的字典的代码可以非常简单。这就是我们所需要的:

    import xml.etree.ElementTree as ET
    
    my_namespaces = dict([node for _, node in ET.iterparse('file.xml',
                                                            events=['start-ns'])])
    

    您不需要使用StringIOopen()。只需将 XML 文件名作为参数提供给 iterparse()

    iterparse() 提供的每个项目都是一个 (event, (prefix, namespace-uri)) 元组。 start-ns 事件在Python 2.7 documentation of iterparse 中没有描述(但在对应的Python 3 documentation 中提及)。


    注意:上面的代码在 CPython 和 Jython 中有效,但在 IronPython 中无效。看 https://github.com/IronLanguages/main/issues/968.

    【讨论】:

    • 我忘了说,我使用的是 IronPython 2.7。我不知道这很重要。我收到一条错误消息:IronPython 不支持iterparse。但奇怪的是,saurabhsuman 的代码并非如此,错误并没有发生。
    • 它应该适用于 IronPython 2.7.9。见github.com/IronLanguages/ironpython2/issues/370
    【解决方案2】:

    您应该在ET.iterparse() 中传递xml 文件的内容,而不是字符串my_schema。

    将代码更改为:

    from io import StringIO
    import xml.etree.ElementTree as ET
    
    xml = "file.xml"
    f = open(xml, "r")
    xml_data = unicode(f.read() , "utf-8") 
    my_namespaces = dict([node for _, node in ET.iterparse(StringIO(xml_data), events=['start-ns'])])
    
    from pprint import pprint
    pprint(my_namespaces)
    

    输出:

    {'': 'http://www.adv-online.de/namespaces/adv/gid/6.0',
     u'adv': 'http://www.adv-online.de/namespaces/adv/gid/6.0',
     u'gco': 'http://www.isotc211.org/2005/gco',
     u'gmd': 'http://www.isotc211.org/2005/gmd',
     u'gml': 'http://www.opengis.net/gml/3.2',
     u'ogc': 'http://www.adv-online.de/namespaces/adv/gid/ogc',
     u'ows': 'http://www.opengis.net/ows',
     u'wfs': 'http://www.adv-online.de/namespaces/adv/gid/wfs',
     u'wfsext': 'http://www.adv-online.de/namespaces/adv/gid/wfsext',
     u'xlink': 'http://www.w3.org/1999/xlink',
     u'xsd': 'http://www.w3.org/2001/XMLSchema',
     u'xsi': 'http://www.w3.org/2001/XMLSchema-instance'}
    

    【讨论】:

    • 感谢您的帮助,但我在此行中有一个 ValueError: write to closed filemy_namespaces = dict([node for _, node in ET.iterparse(StringIO(xml_data), events=['start-ns'])])
    • 您现在可以检查一下编辑后的代码吗,my_namespaces = dict([node for _, node in ET.iterparse(StringIO(xml_data), events=['start-ns'])]) 行应该在 with 块内。
    • block中的codeline出现同一行的相同错误。
    • 你现在可以用编辑后的代码检查一下吗,它在我这边工作
    • 你能发布堆栈跟踪
    猜你喜欢
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    相关资源
    最近更新 更多