我正在解析一个相当大小的xml文件,遇到了一个问题。由于某些原因,我无法提取数据,即使我以前对不同的xml文件做过完全相同的事情。
下面是我的代码片段:(程序的其余部分,我已经测试过了,它们运行得很好)编辑:更改为包含一个测试尝试&除了块
def parseXML():
file = open(str(options.drugxml),'r')
data = file.read()
file.close()
dom = parseString(data)
druglist = dom.getElementsByTagName('drug')
with codecs.open(str(options.csvdata),'w','utf-8') as csvout, open('DrugTargetRel.csv','w') as dtout:
for entry in druglist:
count = count + 1
try:
drugtype = entry.attributes['type'].value
print count
except:
print count
print entry
drugidObj = entry.getElementsByTagName('drugbank-id')[0]
drugid = drugidObj.childNodes[0].nodeValue
drugnameObj = entry.getElementsByTagName('name')[0]
drugname = drugnameObj.childNodes[0].nodeValue
targetlist = entry.getElementsByTagName('target')
for target in targetlist:
targetid = target.attributes['partner'].value
dtout.write((','.join((drugid,targetid)))+'\n')
csvout.write((','.join((drugid,drugname,drugtype)))+'\n')如果您想知道XML文件的模式大致是什么样子,下面是一个糟糕透顶的级别草图:
<drugs>
<drug type='something' ...>
<drugbank-id>
<name>
...
<targets>
<target partner='something'>我在这里输入的那些文件,我需要从XML文件中提取出来,并把它放在csv文件中(如上面的代码所示),而且代码以前也适用于不同的xml文件,不知道为什么它不能处理这个文件。我在“类型”上得到了KeyError,我还在网上发现了索引错误,即使每种药物都有一种药物,但都可以提取药物。我在搞什么鬼?
编辑:我正在提取的东西保证在每种药物中。
对于任何关心此事的人,下面是我正在解析的XML文件的链接:http://www.drugbank.ca/system/downloads/current/drugbank.xml.zip
编辑:在实现了一个try &除块(见上面)之后,我发现了以下内容:在模式中,有一些称为“药物交互”的部分,其中也有一个子字段名为see。就像这样:
<drugs>
<drug type='something' ...>
<drugbank-id>
<name>
...
<targets>
<target partner='something'>
<drug-interactions>
<drug>我想我的药物列表=dom.getElementsByTagName(‘药物’)也是无意中捡到的--我不知道我怎么能解决这个问题.有什么建议吗?
发布于 2013-03-29 20:19:56
基本上,当parsin使用xml时,您不能依赖您知道结构这一事实。找出代码中的结构是一个很好的实践。
因此,每次访问元素或属性时,请先检查是否存在。在您的代码中,它意味着:
确保药物元素上有一个属性“type”:
drugtype = entry.attributes['type'].value if entry.attributes.has_key('type') else 'defaulttype'确保getElementsByTagName在访问其元素之前不返回空数组:
drugbank-id = entry.getElementsByTagName('drugbank-id')
drugidObj = drugbank-id[0] if drugbank-id else None另外,在访问子节点之前,请确保有以下内容:
if drugidObj.hasChildNodes:
drugid = drugidObj.childNodes[0].nodeValue或者使用for循环循环遍历它们。
当您在药物组上调用getElementsByTagName时,它会返回所有元素,包括嵌套元素。若要只获取药物元素(这些元素是药物元素的dirrect子元素),您必须使用childNodes属性。
发布于 2013-03-29 19:44:39
我有一种感觉,也许是因为内存不足或其他原因发生了一些奇怪的事情,所以我用迭代器重写了解析器,并对每种药物进行了测试,并使程序得以完成,而不引起异常。
基本上,我在这里要做的是,不是将整个XML文件加载到内存中,而是解析每个<drug>和</drug>标记的开头和结尾的XML文件。然后每次使用minidom解析。
代码可能有点脆弱,因为我假设每个<drug>和</drug>对都在各自的行上。希望这比伤害更有帮助。
#!python
import codecs
from xml.dom import minidom
class DrugBank(object):
def __init__(self, filename):
self.fp = open(filename, 'r')
def __iter__(self):
return self
def next(self):
state = 0
while True:
line = self.fp.readline()
if state == 0:
if line.strip().startswith('<drug '):
lines = [line]
state = 1
continue
if line.strip() == '</drugs>':
self.fp.close()
raise StopIteration()
if state == 1:
lines.append(line)
if line.strip() == '</drug>':
return minidom.parseString("".join(lines))
with codecs.open('csvout.csv', 'w', 'utf-8') as csvout, open('dtout.csv', 'w') as dtout:
db = DrugBank('drugbank.xml')
for dom in db:
entry = dom.firstChild
drugtype = entry.attributes['type'].value
drugidObj = entry.getElementsByTagName('drugbank-id')[0]
drugid = drugidObj.childNodes[0].nodeValue
drugnameObj = entry.getElementsByTagName('name')[0]
drugname = drugnameObj.childNodes[0].nodeValue
targetlist = entry.getElementsByTagName('target')
for target in targetlist:
targetid = target.attributes['partner'].value
dtout.write((','.join((drugid,targetid)))+'\n')
csvout.write((','.join((drugid,drugname,drugtype)))+'\n')这里有一个有趣的读物,可能对你有进一步的帮助:http://www.ibm.com/developerworks/xml/library/x-hiperfparse/
https://stackoverflow.com/questions/15709499
复制相似问题