我正在尝试(从另一位作者处)修复一些旧代码,似乎找不到以前的结果:
问题的症结在于代码片段:
import lxml.etree
some_xml = open('some.xml','rt').read()
xml_tree = lxml.etree.fromstring(some_xml)
tracks_filter = lxml.etree.XPath(u'//track[@type = $track_type]')
tracks = tracks_filter(xml_tree, track_type = "General")
print("Found %u tracks" % (len(tracks)))
所以我的理解是,给它一堆带有一些节点的XML,找到所有具有“类型”属性(等于“常规”)的节点。因此,在下面的XML中-应该应该找到第一个节点,但是找不到。
XML是(来自mkvinfo,但为简洁起见而被简化):
<?xml version="1.0" encoding="UTF-8"?>
<MediaInfo
xmlns="https://mediaarea.net/mediainfo"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://mediaarea.net/mediainfo https://mediaarea.net/mediainfo/mediainfo_2_0.xsd"
version="2.0">
<creatingLibrary version="17.12" url="https://mediaarea.net/MediaInfo">MediaInfoLib</creatingLibrary>
<media ref="/var/lib/mythtv/recordings/1034_20180715093100.ts">
<track type="General">
<ID>848</ID>
<VideoCount>1</VideoCount>
<AudioCount>1</AudioCount>
<TextCount>1</TextCount>
</track>
<track type="Video">
<StreamOrder>0-0</StreamOrder>
<ID>164</ID>
<MenuID>1</MenuID>
<Format>MPEG Video</Format>
<Format_Version>2</Format_Version>
</track>
<track type="Text">
<ID>45-801</ID>
<MenuID>1</MenuID>
<Format>Teletext Subtitle</Format>
<Language>en</Language>
</track>
</media>
</MediaInfo>
注意:我已经手工编辑了XML代码以减小它的大小,因此任何XML错误可能都是由于我的手工造成的(或缺乏这种错误)。
我希望代码能够解析并找到“ track”项,该项的属性为“ type =“ General”'',但始终找不到任何内容。我尝试修复(更新)的代码包含许多此类解析操作。
感谢您的帮助。
编辑-实际答案:
需要告知XPath XML的名称空间。 这里的命名空间定义为:“ https://mediaarea.net/mediainfo”(XML的第三行)。
因此,过滤器lxml.etree.XPath需要修改其路径,并将名称空间字典传递给它:
tracks_filter = lxml.etree.XPath(u'//i:track[@type = $track_type]', namespaces={'i':'https://mediaarea.net/mediainfo'})
tracks = tracks_filter(xml_tree, track_type = "General")
然后它起作用。