Python从URL读取XML文件及子节点信息访问问题排查
解决Python读取URL中XML并访问子节点的问题
嘿,我看了你的问题,问题确实出在XML的结构——准确说是命名空间在搞鬼!你之前单独测试提取author节点能成功,大概率是因为测试用的XML没有使用命名空间,而你现在访问的DailyMed XML是HL7 SPL格式,根节点自带了命名空间,导致直接用findall('title')找不到对应的节点。
为什么你的代码找不到title节点?
打开你提供的URL对应的XML,根节点会类似这样:
<spl xmlns="http://hl7.org/v3" ...>
这里的xmlns="http://hl7.org/v3"就是命名空间,ElementTree在解析时会把所有子节点都归到这个命名空间下。你直接写findall('title'),相当于查找没有命名空间的title节点,自然返回空列表。
修正后的代码示例
下面两种方法都能解决这个问题,选你觉得顺手的就行:
方法1:直接使用命名空间URI查找
import urllib import xml.etree.ElementTree as ET url = 'https://dailymed.nlm.nih.gov/dailymed/services/v2/spls/fe9e8b7d-61ea-409d-84aa-3ebd79a046b5.xml' print 'Retrieving', url document = urllib.urlopen(url).read() print 'Retrieved', len(document), 'characters.' print document[:50] tree = ET.fromstring(document) # 对应XML根节点的命名空间URI namespace = '{http://hl7.org/v3}' # 用.//来匹配所有层级的title节点(不管它在XML的哪个位置) lst = tree.findall('.//' + namespace + 'title') print '找到', len(lst), '个title节点:' for item in lst[:5]: # 打印前5个节点内容看看 print item.text
方法2:用命名空间映射让代码更清晰
这种方法适合XML有多个命名空间的场景,可读性更好:
import urllib import xml.etree.ElementTree as ET url = 'https://dailymed.nlm.nih.gov/dailymed/services/v2/spls/fe9e8b7d-61ea-409d-84aa-3ebd79a046b5.xml' print 'Retrieving', url document = urllib.urlopen(url).read() print 'Retrieved', len(document), 'characters.' print document[:50] tree = ET.fromstring(document) # 定义命名空间映射,前缀可以自定义(比如这里用hl7) ns_map = {'hl7': 'http://hl7.org/v3'} # 使用XPath语法,通过前缀指定命名空间 lst = tree.findall('.//hl7:title', namespaces=ns_map) print '找到', len(lst), '个title节点:' for item in lst[:5]: print item.text
额外提示
如果你要找的是特定层级的title节点,可以把.//换成具体的路径,比如如果title在/spl/component/section/title下,就写hl7:spl/hl7:component/hl7:section/hl7:title(对应方法2),这样能更精准地定位节点。
内容的提问来源于stack exchange,提问作者PANKAJ KUMAR
相关产品推荐
相关产品推荐

