【问题标题】:parsing xml using python / elementree使用 python / elementtree 解析 xml
【发布时间】:2016-06-21 11:30:46
【问题描述】:

我需要搜索的 xml 指定但不使用命名空间:

    <WRMHEADER xmlns="http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader" version="4.0.0.0">
    <DATA>
        <PROTECTINFO>
            <KEYLEN>16</KEYLEN>
            <ALGID>AESCTR</ALGID>
        </PROTECTINFO>

        <LA_URL>http://192.168.8.33/license/rightsmanager.asmx</LA_URL>
        <LUI_URL>http://192.168.8.33/license/rightsmanager.asmx</LUI_URL>

        <DS_ID></DS_ID>
        <KID></KID>
        <CHECKSUM></CHECKSUM>

    </DATA>
</WRMHEADER>

我想读取各个字段的值,例如数据/protectinfo/keylen 等

root    = ET.fromstring(sMyXml)
keylen  = root.findall('./DATA/PROTECTINFO/KEYLEN')

print root
print keylen

此代码打印以下内容:

<Element {http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader}WRMHEADER at 0x7f2a7c35be60>
[]

root.find 和 root.findall 对此查询返回 None 或 []。我一直无法指定默认命名空间,是否有查询这些值的解决方案? 谢谢

【问题讨论】:

    标签: python xml elementtree


    【解决方案1】:

    创建命名空间字典:

    x = """<WRMHEADER xmlns="http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader" version="4.0.0.0">
        <DATA>
            <PROTECTINFO>
                <KEYLEN>16</KEYLEN>
                <ALGID>AESCTR</ALGID>
            </PROTECTINFO>
    
            <LA_URL>http://192.168.8.33/license/rightsmanager.asmx</LA_URL>
            <LUI_URL>http://192.168.8.33/license/rightsmanager.asmx</LUI_URL>
    
            <DS_ID></DS_ID>
            <KID></KID>
            <CHECKSUM></CHECKSUM>
    
        </DATA>
    </WRMHEADER>"""
    from xml.etree import ElementTree as ET
    
    root = ET.fromstring(x)
    ns = {"wrm":"http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader"}
    keylen = root.findall('wrm:DATA', ns)
    
    print root
    print keylen
    

    现在你应该得到类似的东西:

    <Element '{http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader}WRMHEADER' at 0x7fd0a30d45d0>
    [<Element '{http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader}DATA' at 0x7fd0a30d4610>]
    

    获取/DATA/PROTECTINFO/KEYLEN

    In [17]: root = ET.fromstring(x)
    
    In [18]: ns = {"wrm":"http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader"} 
    In [19]: root.find('wrm:DATA/wrm:PROTECTINFO/wrm:KEYLEN', ns).text
    Out[19]: '16'
    

    【讨论】:

    • 不用担心,如果您在 python 中使用 xml 做了大量工作,您可能会发现 lxml 很有用 lxml.de
    【解决方案2】:

    我想知道这是否也有效。请在您的 cmets 上发表这种方法的优缺点。

    from xml.dom.minidom import parse
    import xml.dom.minidom
    
    # Open XML document using minidom parser
    DOMTree = xml.dom.minidom.parse("xmlquestion.xml")
    tn = DOMTree.documentElement
    print tn.namespaceURI
    #print tn.childNodes
    
    data = tn.getElementsByTagName('DATA')[0]
    protectinfo = data.getElementsByTagName('PROTECTINFO')[0]
    keylen = protectinfo.getElementsByTagName('KEYLEN')[0]
    print keylen.childNodes[0].data
    
    http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader
    16
    

    【讨论】:

    • 太好了。由于我的数据源来自网络请求,因此我不得不稍作修改以导入 parseString。我只是在寻找一种快速验证 xml 内容的方法。我想选择 ET,因为它似乎被更广泛地使用,尽管我发现这个问题令人沮丧,因为文档似乎缺乏而且这似乎是一个基本问题。
    猜你喜欢
    • 2021-02-06
    • 2017-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多