Python解析XML
软件测试老师布置的实验,解析xml,因为是小白,所以刚做这题很棘手,百度搜了好多python解析xml,都相对而言太基础,举的例子,就是一个父节点带一个子节点,标签屈指可数,直接get标签名就得到了,但是由于老师布置的内容特别复杂,一个网页的内容支离破碎,所以网上的东西满足不了我这个不会动脑筋的人,看了半天也反思不起来,于是就只能研究下xml书了。还是有点瑕疵,有时间再改,废话不说嫩多了,例子如下
一、需要解析的xml新闻文档
<?xml version="1.0" encoding="UTF-8" ?>
<Body>
<Title>成都网友称震感强烈 女同事当即哭泣</Title>
<ReportTime type="absTime">2008年05月12日16:15</ReportTime>
<Content>
<Paragraph>
<Sentence>
<Event eid="e1">
<Time type="relTime" tid="t1">5月12日14时28分</Time>,
<Location lid="l1">四川</Location>发生7.8级
<Denoter type="emergency" did="d1">地震</Denoter>。
</Event>
</Sentence>
</Paragraph>
<Paragraph>
<Sentence>
<Event eid="e2">
<Time type="absTime" tid="t2">15时50分</Time>,新民网
<Participant sid="s1">记者</Participant>网上
<Denoter type="action" did="d2">连线</Denoter>成都网友
<Participant oid="o2">姚先生</Participant>
</Event>。
</Sentence>
<Sentence>
<Event eid="e3"><Participant sid="s3,s4,s6,s7,s8,s9,s10">姚先生</Participant><Time type="relTime" tid="t3">当时</Time>正在<Location lid="l3">成都市武侯区的办公室</Location><Denoter type="action" did="d3">打电话</Denoter>,</Event>
<Event eid="e4" type="thoughtevent" >突然
<Denoter type="statement" did="d4">感觉</Denoter>
</Event>
<Event eid="e5"><Object oid="o5">电脑显示器</Object><Denoter type="action" did="d5">晃</Denoter>得很厉害</Event>,
<Event eid="e6">便<Denoter type="action" did="d6">丢下</Denoter><Object oid="o6">电话</Object></Event>、
<Event eid="e7"><Denoter type="action" did="d7">抓起</Denoter><Object oid="o7">手机</Object>和<Object oid="o7">钱包</Object></Event>
<Event eid="e8">往外<Denoter type="action" did="d8">跑</Denoter>,</Event>
<Event eid="e9">手里还<Denoter type="action" did="d9">拿</Denoter>着<Object oid="o9">无绳电话子机</Object>,</Event>
<Event type="thoughtevent" eid="e10">准备给远在江苏的<Participant type="recipient" oid="o10">家人</Participant><Denoter type="action" did="d10">打电话</Denoter>。</Event>
</Sentence>
</Paragraph>
<Paragraph>
<Sentence>
<Event eid="e11" type="thoughtevent"><Participant type="agent" sid="s11">姚先生</Participant><Denoter type="statement" did="d11">说</Denoter></Event>
<Event eid="e12">坐在他旁边的<Participant type="agent" sid="s12,s13">女同事</Participant>立刻<Denoter type="perception" did="d12">感觉</Denoter>是在地震,</Event>
<Event eid="e13">一下子<Denoter type="action" did="d13">哭</Denoter>了起来。</Event>
</Sentence>
<Sentence>
<Event eid="e14" type="thoughtevent">据<Participant sid="s14">姚先生</Participant><Denoter type="statement" did="d14">介绍</Denoter>,</Event>
<Event eid="e15">成都市很多钢结构的<Object oid="o15">房屋</Object>都有明显<Denoter type="emergency" did="d15">震感</Denoter>,</Event>
<Event eid="e16">当<Participant oid="o16">他</Participant>和<Participant>很多市民</Participant>一样<Denoter type="operation" did="d16">疏散</Denoter>到<Location type="destination" lid="l16">室外</Location>时,</Event>
<Event eid="e17" type="thoughtevent">随即<Denoter type="perception" did="d17">发现</Denoter></Event>
<Event eid="e18"><Object oid="o18">手机信号</Object>已经<Denoter type="stateChange" did="d18">中断</Denoter></Event>,据称基站坏了。
</Sentence>
<Sentence>
<Event eid="e19">疏散出来的人群中,<Participant sid="s19">大家</Participant>都在<Denoter type="action" did="d19">谈论</Denoter>唐山大地震。</Event>
</Sentence>
</Paragraph>
<Paragraph>
<Sentence>
<Event eid="e20" type="thoughtevent"><Participant sid="s20">姚先生</Participant>向<Participant oid="o20">新民网记者</Participant><Denoter type="perception" did="d20">称</Denoter></Event>,
<Event eid="e21" type="thoughtevent">据<Participant sid="s21">一些成都市民</Participant><Denoter type="perception" did="d21">说</Denoter>,</Event>
<Event eid="e22">成都的<Object oid="o22">伊藤洋华堂武侯店</Object><Denoter type="stateChange" did="d22">倒塌</Denoter>。</Event>
</Sentence>
</Paragraph>
</Content>
<eRelation thoughtcontent_eids="e5" thoughtevent_eid="e4" relType="Thoughtcontent"/>
<eRelation thoughtcontent_eids="e12-e13" thoughtevent_eid="e11" relType="Thoughtcontent"/>
<eRelation thoughtcontent_eids="e15-e16" thoughtevent_eid="e14" relType="Thoughtcontent"/>
<eRelation thoughtcontent_eids="e18" thoughtevent_eid="e17" relType="Thoughtcontent"/>
<eRelation thoughtcontent_eids="e21-e22" thoughtevent_eid="e20" relType="Thoughtcontent"/>
<eRelation thoughtcontent_eids="e22" thoughtevent_eid="e21" relType="Thoughtcontent"/>
<eRelation relType="Causal" cause_eid="e1" effect_eid="e5"/>
<eRelation relType="Causal" cause_eid="e12" effect_eid="e13"/>
<eRelation relType="Causal" cause_eid="e1" effect_eid="e15"/>
<eRelation relType="Causal" cause_eid="e1" effect_eid="e18"/>
<eRelation relType="Causal" cause_eid="e1" effect_eid="e22"/>
</Body>
二、python解析步骤
from xml.dom.minidom import parse
import xml.dom.minidom
#dom解析xml
DOMTree = xml.dom.minidom.parse("D:\\QQPCmgr\\Desktop\\2.xml")
#返回文档的根节点
root1 = DOMTree.documentElement
#观察新闻发现,内容都在Event元素下
ContentNodes = root1.getElementsByTagName("Event")
#定义一个字符串,保存解析出的数据
content = ""
#遍历所有的Event
for i in range(len(ContentNodes)):
#获取第i个Event下的子节点
SonNodes = ContentNodes[i].childNodes
#遍历Event下的所有子节点
for j in range(len(SonNodes)):
print(SonNodes[j].nodeName)
输出:
Time
#text
Location
#text
Denoter
#text
************此处省略后文****************
for i in range(len(ContentNodes)):
#获取第i个Event下的子节点
# print(ContentNodes[i].attributes)
SonNodes = ContentNodes[i].childNodes
#遍历Event下的所有子节点
for j in range(len(SonNodes)):
# print(SonNodes[j].nodeName)
#获取所有Event下的所有子节点名字 #text是内容 要去掉,
content += SonNodes[j].firstChild.data
#获取所有Event下的值,不包含在Event子节点的值
if(ContentNodes[i].childNodes[j].nodeValue!=None):
content+= ContentNodes[i].childNodes[j].nodeValue
AttributeError: 'NoneType' object has no attribute 'data'
原因是那个#text 所以我们要把它去掉
输出event值要加判断
if(ContentNodes[i].childNodes[j].nodeValue!=None):
content+= ContentNodes[i].childNodes[j].nodeValue
None
,
None
发生7.8级
None
,
成都的
None
None
****************此处省略后文**************
如果不加判断就会有None
三、 完整代码
from xml.dom.minidom import parse
import xml.dom.minidom
#dom解析xml
DOMTree = xml.dom.minidom.parse("D:\\QQPCmgr\\Desktop\\2.xml")
#返回文档的根节点
root1 = DOMTree.documentElement
#观察新闻发现,内容都在Event元素下
ContentNodes = root1.getElementsByTagName("Event")
#定义一个字符串,保存解析出的数据
content = ""
#遍历所有的Event
for i in range(len(ContentNodes)):
#获取第i个Event下的子节点
SonNodes = names[i].childNodes
#遍历Event下的所有子节点
for j in range(len(SonNodes)):
#print(SonNodes[j].nodeName)
#获取所有Event下的所有子节点名字 #text是内容 要去掉,
if(SonNodes[j].nodeName!="#text"):
content += SonNodes[j].firstChild.data
#获取所有Event下的值,不包含在Event子节点的值
if(ContentNodes[i].childNodes[j].nodeValue!=None):
content+= ContentNodes[i].childNodes[j].nodeValue
print(content)
四、结果
5月12日14时28分,四川发生7.8级地震。15时50分,
新民网记者网上连线成都网友姚先生姚先生当时正在成都市武侯区的办公室打电话,
突然感觉电脑显示器晃得很厉害便丢下电话抓起手机和钱包往外跑,手里还拿着无绳电话子机,准备给远在江苏的家人打电话。
姚先生说坐在他旁边的女同事立刻感觉是在地震,一下子哭了起来。据姚先生介绍,成都市很多钢结构的房屋都有明显震感,
当他和很多市民一样疏散到室外时,随即发现手机信号已经中断疏散出来的人群中,大家都在谈论唐山大地震。
姚先生向新民网记者称据一些成都市民说,成都的伊藤洋华堂武侯店倒塌。
五、总结
本文利用的是Dom解析的XML
用到了的方法有
1 dom解析xml:xml.dom.minidom.parse
2 获取指定标签:getElementsByTagName
3 获取标签下子节点:ContentNodes[i].childNodes
4 获取元素名称:SonNodes[j].nodeName
5 返回根节点:DOMTree.documentElement
6 获取Element属性:ContentNodes[i].attributes
7 获取Element属性的值:ContentNodes[i].attributes.value