Python 解析 XML 数据的正确姿势( 三 )


  • branch {'name': 'invalid'}
  • 我们还可以通过索引值来访问特定的子元素:
     
    1. >>> root[0].tag, root[0].text
    2. ('branch', 'n text,sourcen ')
     
    查找需要的元素从上面的示例中,可以明显发现我们能够通过简单的递归方法(对每一个元素,递归式访问其所有子元素)获取树中的所有元素 。但是,由于这是十分常见的工作,ET提供了一些简便的实现方法 。
    Element对象有一个iter方法,可以对某个元素对象之下所有的子元素进行深度优先遍历(DFS) 。ElementTree对象同样也有这个方法 。下面是查找XML文档中所有元素的最简单方法:
     
    1. >>> for elem in tree.iter:
    2. ... print elem.tag, elem.attrib
    3. ...
    4. doc {}
    5. branch {'hash': '1cdf045c', 'name': 'codingpy.com'}
    6. branch {'hash': 'f200013e', 'name': 'release01'}
    7. sub-branch {'name': 'subrelease01'}
    8. branch {'name': 'invalid'}
    在此基础上,我们可以对树进行任意遍历——遍历所有元素,查找出自己感兴趣的属性 。但是ET可以让这个工作更加简便、快捷 。iter方法可以接受tag名称,然后遍历所有具备所提供tag的元素:
     
    1. >>> for elem in tree.iter(tag='branch'):
    2. ... print elem.tag, elem.attrib
    3. ...
    4. branch {'hash': '1cdf045c', 'name': 'codingpy.com'}
    5. branch {'hash': 'f200013e', 'name': 'release01'}
    6. branch {'name': 'invalid'}
     
    支持通过XPath查找元素使用XPath查找感兴趣的元素,更加方便 。Element对象中有一些find方法可以接受Xpath路径作为参数,find方法会返回第一个匹配的子元素,findall以列表的形式返回所有匹配的子元素,iterfind则返回一个所有匹配元素的迭代器(iterator) 。ElementTree对象也具备这些方法,相应地它的查找是从根节点开始的 。
    下面是一个使用XPath查找元素的示例:
     
    1. >>> for elem in tree.iterfind('branch/sub-branch'):
    2. ... print elem.tag, elem.attrib
    3. ...
    4. sub-branch {'name': 'subrelease01'}
    上面的代码返回了 branch元素之下所有tag为sub-branch的元素 。接下来查找所有具备某个name属性的branch元素:
     
    1. >>> for elem in tree.iterfind('branch[@name="release01"]'):
    2. ... print elem.tag, elem.attrib
    3. ...
    4. branch {'hash': 'f200013e', 'name': 'release01'}
     
    构建XML文档利用ET,很容易就可以完成XML文档构建,并写入保存为文件 。ElementTree对象的write方法就可以实现这个需求 。
    一般来说,有两种主要使用场景 。一是你先读取一个XML文档,进行修改,然后再将修改写入文档,二是从头创建一个新XML文档 。
    修改文档的话,可以通过调整 Element对象来实现 。请看下面的例子:
     
    1. >>> root = tree.getroot
    2. >>> del root[2]
    3. >>> root[0].set('foo', 'bar')
    4. >>> for subelem in root:
    5. ... print subelem.tag, subelem.attrib
    6. ...
    7. branch {'foo': 'bar', 'hash': '1cdf045c', 'name': 'codingpy.com'}
    8. branch {'hash': 'f200013e', 'name': 'release01'}
    在上面的代码中,我们删除了root元素的第三个子元素,为第一个子元素增加了新属性 。这个树可以重新写入至文件中 。最终的XML文档应该是下面这样的:
     


    推荐阅读