ElementTree中findall函数的原因不明原因

时间:2014-02-12 15:24:07

标签: python xml xml-parsing elementtree

我有以下有问题的代码:

import xml.etree.ElementTree as ET    

def main():
    tree = ET.parse('D:/Developer/Work/oDesk1/assets/test.xml')
    root = tree.getroot()
    print root.findall('.//country')

if __name__ == '__main__':
    main()

我有以下XML:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="recipes.xsl"?>
<data xmlns="urn:Test" xmlns:xs="http://www.w3.org/2001/XMLSchema" name="Galaxy" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:Test test.xsd">
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

问题:

root.findall('.// country')返回一个空列表。

预期:

root.findall('.// country')应该返回一个填充的列表。

将XML数据更改为以下内容可以解决我的问题。

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="recipes.xsl"?>
<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

我无法理解这种未定义的行为。我知道以前的XML指向某些XML模式。我想绕过XML模式信息而不编辑XML文件,以便在调用root.findall()函数时获得填充列表。我该怎么做?另外,请用两个略有不同的XML解释这种奇怪的行为。

1 个答案:

答案 0 :(得分:2)

etree只是没有很好地处理名称空间。 您需要使用自己的语法自己包含它:

root.findall('.//{urn:Test}country')

将返回预期的元素。

findall采用可选的名称空间参数,但它似乎不适用于“空”隐式名称空间