我使用xml sax解析器来解析xml文件,下面是我的代码
xml文件代码:
<job>
<title>Registered Nurse-Epilepsy</title>
<job-code>881723</job-code>
<detail-url>http://search.careers-hcanorthtexas.com/s/Job-Details/Registered-Nurse-Epilepsy-Job/Medical-City/xjdp-cl289619-jf120-ct2181-jid4041800?s_cid=Advance
</detail-url>
<job-category>Neuroscience Nursing</job-category>
<description>
<summary>
<div class='descriptionheader'>Description</div><P STYLE="margin-top:0px;margin-bottom:0px"><SPAN STYLE="font-family:Arial;font-size:small">Utilizing the standards set forth for Nursing Practice by the ANA and ONS, the RN will organize, modify, evaluate, document and maintain the plan of care for Epilepsy and/or Neurological patients. It will include individualized, family centered, holistic, supportive, and safe age-specific care.</SPAN></P><div class='qualificationsheader'>Qualifications</div><UL STYLE="list-style-type:disc"> <LI>Graduate of an accredited school of Professional Nursing.</LI> <LI>BSN preferred </LI> <LI>Current licensure with the Board of Nurse Examiners for the State of Texas</LI> <LI>Experience in Epilepsy Monitoring and/or Neurological background preferred.</LI> <LI>ACLS preferred, within 6 months of hire</LI> <LI>PALS required upon hire</LI> </UL>
</summary>
</description>
<posted-date>2012-07-26</posted-date>
<location>
<address>7777 Forest Lane</address>
<city>Dallas</city>
<state>TX</state>
<zip>75230</zip>
<country>US</country>
</location>
<company>
<name>Medical City (Dallas, TX)</name>
<url>http://www.hcanorthtexas.com/careers/search-jobs.dot</url>
</company>
</job>
Python代码 :(部分代码清除我的怀疑,直到启动元素功能)
from xml.sax.handler import ContentHandler
import xml.sax
import xml.parsers.expat
import ConfigParser
import xml.sax
class Exact(xml.sax.handler.ContentHandler):
def __init__(self):
self.curpath = []
def startElement(self, name, attrs):
print name,attrs
self.clearFields()
def endElement(self, name):
pass
def characters(self, data):
self.buffer += data
def clearFields():
self.fields = {}
self.fields['title'] = None
self.fields['job-code'] = None
self.fields['detail-url'] = None
self.fields['job-category'] = None
self.fields['description'] = None
self.fields['summary'] = None
self.fields['posted-date'] = None
self.fields['location'] = None
self.fields['address'] = None
self.fields['city'] = None
self.fields['state'] = None
self.fields['zip'] = None
self.fields['country'] = None
self.fields['company'] = None
self.fields['name'] = None
self.fields['url'] = None
self.buffer = ''
if __name__ == '__main__':
parser = xml.sax.make_parser()
handler = Exact()
parser.setContentHandler(handler)
parser.parse(open('/path/to/xml_file.xml'))
结果: 上述打印陈述的结果如下:
job <xml.sax.xmlreader.AttributesImpl instance at 0x2c0ba70>
title <xml.sax.xmlreader.AttributesImpl instance at 0x2c0ba70>
job-code <xml.sax.xmlreader.AttributesImpl instance at 0x2c0ba70>
detail-url <xml.sax.xmlreader.AttributesImpl instance at 0x2c0ba70>
job-category <xml.sax.xmlreader.AttributesImpl instance at 0x2c0ba70>
description <xml.sax.xmlreader.AttributesImpl instance at 0x2c0ba70>
summary <xml.sax.xmlreader.AttributesImpl instance at 0x2c0ba70>
posted-date <xml.sax.xmlreader.AttributesImpl instance at 0x2c0ba70>
location <xml.sax.xmlreader.AttributesImpl instance at 0x2c0ba70>
address <xml.sax.xmlreader.AttributesImpl instance at 0x2c0ba70>
city <xml.sax.xmlreader.AttributesImpl instance at 0x2c0ba70>
state <xml.sax.xmlreader.AttributesImpl instance at 0x2c0ba70>
zip <xml.sax.xmlreader.AttributesImpl instance at 0x2c0ba70>
country <xml.sax.xmlreader.AttributesImpl instance at 0x2c0ba70>
company <xml.sax.xmlreader.AttributesImpl instance at 0x2c0ba70>
name <xml.sax.xmlreader.AttributesImpl instance at 0x2c0ba70>
url <xml.sax.xmlreader.AttributesImpl instance at 0x2c0ba70>
正如您在上面所述,我从print语句中得到name
和attrs
,但是
现在我的目的是获取该名称的值,如何获取上述所有标签的值,因为我只获取节点名称而不是值。
已编辑的代码:
我真的很困惑如何将数据从节点映射到字典中的键,如上所述
答案 0 :(得分:6)
要获取元素的内容,您需要覆盖characters
方法...将其添加到您的处理程序类:
def characters(self, data):
print data
请注意这一点:解析器不需要在一个块中提供所有数据。您应该使用内部缓冲区并在需要时读取它。在我的大多数xml / sax代码中,我都这样做:
class MyHandler(xml.sax.handler.ContentHandler):
def __init__(self):
self._charBuffer = []
def _flushCharBuffer(self):
s = ''.join(self._charBuffer)
self._charBuffer = []
return s
def characters(self, data):
self._charBuffer.append(data)
...然后在我需要数据的元素末尾调用flush方法。
对于整个用例 - 假设您有一个包含多个作业描述的文件,并且想要一个包含每个作业的作业列表的字段,请执行以下操作:
class MyHandler(xml.sax.handler.ContentHandler):
def __init__(self):
self._charBuffer = []
self._result = []
def _getCharacterData(self):
data = ''.join(self._charBuffer).strip()
self._charBuffer = []
return data.strip() #remove strip() if whitespace is important
def parse(self, f):
xml.sax.parse(f, self)
return self._result
def characters(self, data):
self._charBuffer.append(data)
def startElement(self, name, attrs):
if name == 'job': self._result.append({})
def endElement(self, name):
if not name == 'job': self._result[-1][name] = self._getCharacterData()
jobs = MyHandler().parse("job-file.xml") #a list of all jobs
如果您只需要一次解析一个作业,可以简化列表部分并丢弃startElement
方法 - 只需将_result设置为dict并直接在endElement
中分配给它
答案 1 :(得分:3)
要获取节点的文本内容,您需要实现一个字符方法。例如。
class Exact(xml.sax.handler.ContentHandler):
def __init__(self):
self.curpath = []
def startElement(self, name, attrs):
print name,attrs
def endElement(self, name):
print 'end ' + name
def characters(self, content):
print content
输出:
job <xml.sax.xmlreader.AttributesImpl instance at 0xb6d9baec>
title <xml.sax.xmlreader.AttributesImpl instance at 0xb6d9bb0c>
Registered Nurse-Epilepsy
end title
job-code <xml.sax.xmlreader.AttributesImpl instance at 0xb6d9bb2c>
881723
end job-code
detail-url <xml.sax.xmlreader.AttributesImpl instance at 0xb6d9bb2c>
http://search.careers-hcanorthtexas.com/s/Job-Details/Registered-Nurse-Epilepsy-Job/Medical-City/xjdp-cl289619-jf120-ct2181-jid4041800?s_cid=Advance
end detail-url
(狙击)
答案 2 :(得分:1)
您还需要实施characters
handler:
def characters(self, content):
print content
但是这可能会以块的形式提供文本,而不是每个标记一个块。
尽管如此,请使用ElementTree API代替您;与XML DOM API相比,该API远比pythononic更容易使用。
from xml.etree import ElementTree as ET
etree = ET.parse('/path/to/xml_file.xml')
jobtitle = etree.find('job/title').text
如果您想要的只是直接转换为字典,请查看这个方便的ActiveState Python Cookbook配方:Converting XML to dictionary and back。请注意,它也使用ElementTree API。
如果您想要查找一组现有元素,只需在find()
方法中使用这些元素:
fieldnames = [
'title', 'job-code', 'detail-url', 'job-category', 'description',
'summary', 'posted-date', 'location', 'address', 'city', 'state',
'zip', 'country', 'company', 'name', 'url']
fields = {}
etree = ET.parse('/path/to/xml_file.xml')
for field in fieldnames:
elem = etree.find(field)
if field is not None and field.text is not None:
fields[field] = elem.text
答案 3 :(得分:1)
我建议使用pulldom。这允许您使用sax解析器加载doc,当您找到您感兴趣的节点时,只将该节点加载到dom片段中。
以下是一篇关于使用它的文章:https://www.ibm.com/developerworks/xml/library/x-tipulldom/index.html