Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:使用小型dom通过XML进行解析_Python_Xml_Parsing_Text Parsing - Fatal编程技术网

Python:使用小型dom通过XML进行解析

Python:使用小型dom通过XML进行解析,python,xml,parsing,text-parsing,Python,Xml,Parsing,Text Parsing,我正在解析一个相当大的xml文件,遇到了一个问题。由于某种原因,我无法提取数据,即使我以前在不同的xml文件上做过完全相同的事情 下面是我的一段代码:(程序的其余部分,我已经测试过了,它们工作得很好) 编辑:更改为包含测试尝试块(&E) def parseXML(): file = open(str(options.drugxml),'r') data = file.read() file.close() dom = parseString(data) d

我正在解析一个相当大的xml文件,遇到了一个问题。由于某种原因,我无法提取数据,即使我以前在不同的xml文件上做过完全相同的事情

下面是我的一段代码:(程序的其余部分,我已经测试过了,它们工作得很好) 编辑:更改为包含测试尝试块(&E)

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文件工作过,不确定为什么它不能在这个文件上工作。我在“type”上得到了KeyError,在提取药物ID的行上也得到了索引错误,即使每个药物都有一个药物ID。我搞砸了什么

编辑:我提取的东西保证在每种药物中

对于任何关心此事的人,这里是指向我正在解析的XML文件的链接:

编辑:在实现try&except块(见上文)后,我发现: 在模式中,有一些称为“药物相互作用”的部分,也有一个称为药物的子字段。所以像这样:

 <drugs>
       <drug type='something' ...>
          <drugbank-id>
          <name>
          ...
          <targets>
             <target partner='something'>
          <drug-interactions>
             <drug>

...

我认为我的行druglist=dom.getElementsByTagName('Druge')也无意中拾取了这些内容--我不知道如何修复此问题。。。有什么建议吗?

我有一种感觉,可能是由于内存不足或其他原因而发生了一些奇怪的事情,所以我使用迭代器对每种药物重写了解析器,并进行了尝试,让程序在没有引发异常的情况下完成

基本上,我在这里做的是,不将整个XML文件加载到内存中,而是解析每个
标记的开头和结尾的XML文件。然后每次我都用minidom解析它

代码可能有点脆弱,因为我假设每个
对都在各自的行中。希望它能帮助你,而不是伤害你

#!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')
#!python
导入编解码器
从xml.dom导入minidom
类别银行(对象):
def uuu init uuu(self,文件名):
self.fp=open(文件名'r')
定义(自我):
回归自我
def next(自我):
状态=0
尽管如此:
line=self.fp.readline()
如果state==0:

如果line.strip().startswith('基本上是在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
此外,在访问childnodes之前,请确保存在以下内容:

if drugidObj.hasChildNodes:
    drugid = drugidObj.childNodes[0].nodeValue
或者使用for循环来循环它们


当您在Druges元素上调用
getElementsByTagName
时,它会返回所有元素,包括嵌套的元素。要仅获取Druge元素,即drugs元素的直接子元素,您必须使用
childNodes
属性。

是否可以包含错误的堆栈跟踪?是的,经过编辑,以使最近的两个错误除了添加/删除打印语句之外,在没有进行太多更改的情况下遇到。您的代码假定记录始终具有您认为它们具有的格式。KeyError只是意味着drug元素没有类型属性。Indexer出现类似问题…记录没有您想要的信息。请尝试在druglist中输入“for entry:”将块放入try/except块中,然后打印导致问题的条目。它看起来正确吗?从长远来看,except处理程序会实现您的失败策略(继续处理、报告记录或其他)@tdelaney一开始我认为这可能是导致错误的原因,但当我检查数据时,每个药物字段都有一个type属性,每个药物都必须有一个药物id和药物名称。我甚至用数据源检查了这一点。他们中的每一个都必须在那里。这就是我被难住的原因。我将放入try/except块并制作一些更多检查。@Joe If drugs是根元素,它只有Druge,因为后续元素在drugs上使用childNodes而不是getElementsByTagName。很好,我会看一看。我最终也自己解决了这个问题,但我也会尝试一下。谢谢!