[英]Dynamic search through xml attributes using lxml and xpath in python
我正在努力将下一个xml数据移动到分层数据框架中。 感谢SO的帮助,我能够从xml中获取所有数据。 但是,现在,我要清理提取的数据并在输出之前对其进行整形,因为我将做数千次。
更新:这就是我想要的。 我似乎无法动态获取channel
的Time
和value
。 频道名称将随每个文件而变化。
当channel = txt1[0]
(对于此文件, txt1[0]="blah"
)到channel = txt1[8]
(对于此文件, txt1[8]="lir"
)
channel Time value
0 blah 2013-05-01 00:00:00 258
1 blah 2013-05-01 00:01:00 259
...
n-2 lir 2013-05-01 23:57:00 58
n-1 lir 2013-05-01 23:58:00 37
n lir 2013-05-01 23:59:00 32
这是我的xml文件的获取和结构方式:
import requests
from lxml import etree, objectify
r = requests.get('https://api.stuff.us/place/getData? security_key=key&period=minutes&startTime=2013-05-01T00:00&endTime=2013-05-01T23:59&sort=channel') #edited for privacy
root = etree.fromstring(r.text)
xml_new = etree.tostring(root, pretty_print=True)
print xml_new[300:900] #gives xml output to show structure
<startTime>2013-05-01 00:00:00</startTime>
<endTime>2013-05-01 23:59:00</endTime>
<summaryPeriod>minutes</summaryPeriod>
<data>
<channel channel="97925" name="blah">
<Time Time="2013-05-01 00:00:00">
<value>258</value>
</Time>
<Time Time="2013-05-01 00:01:00">
<value>259</value>
</Time>
<Time Time="2013-05-01 00:02:00">
<value>258</value>
</Time>
<Time Time="2013-05-01 00:03:00">
<value>257</value>
</Time>
昨天,我在SO上问过此问题,并解决了将time
和value
值放入数据帧的问题:将xml解析为pandas数据帧会引发内存错误
dTime=[]
dvalue=[]
for df in root.xpath('//channel/Time'):
## Iterate over attributes of Time but Time only has one attrib [@Time]
for attrib in df.attrib:
dTime.append(df.attrib[attrib])
## value is a child of time, and iterate
subfields = df.getchildren()
for subfield in subfields:
dvalue.append(subfield.text)
pef=DataFrame({'Time':dTime,'values':dvalue})
pef
<class 'pandas.core.frame.DataFrame'>
Int64Index: 12960 entries, 0 to 12959
Data columns (total 2 columns):
Time 12960 non-null values
value 12960 non-null values
dtypes: object(2)
pef[:5]
Time value
0 2013-05-01 00:00:00 258
1 2013-05-01 00:01:00 259
2 2013-05-01 00:02:00 258
3 2013-05-01 00:03:00 257
4 2013-05-01 00:04:00 257
现在,我正在分别处理每个通道的数据(结构是channel
> Time
> value
),以便可以将通道插入为数据集的列。
因此,我决定动态获取通道名称并搜索数据。对于此文件,有九个单独的有效通道名称,但对于所有文件(编号或名称)来说都不相同。
txt1 = root.xpath('//channel/@name') #this prints all channel names!
len(txt1)
Out[67]: 9
print txt1
['blah', 'b', 'c', 'd', 'vd', 'ef', 'fg', 'kc', 'lir']
我以为我可以动态获取数据(使用较早的解决方案,但添加@name=txt1[0]
)并最终for i = 0 to len(txt1), ...
以遍历所有数据。 但是我得到一个空的数据框:
dTime=[]
dchannel = txt1[0] # can hardcode, but need to be able to get all
dvalue=[]
for df in root.xpath('//channel[@name=txt1[0]]/Time'):
#CODE NEEDED: to get dchannel to dynamically = channel[@name]
## Iterate over attributes of time for specific channel
for attrib in df.attrib:
dTime.append(df.attrib[attrib])
## value is a child of time, and iterate
subfields = df.getchildren()
for subfield in subfields:
dvalue.append(subfield.text)
perf=DataFrame({'Channel': dchannel,'Time':dTime,'values':dvalue})
perf
Int64Index([], dtype=int64)
Empty DataFrame
如果我对所需的属性进行硬编码,例如for df in root.xpath('/*/*/*/channel[@name="blah"]/Time'):
它将为一个属性打印它,但我无法获取它可以参考txt1[]
来工作。
我尝试参考{0}..., txt1[]
但是随后它为dchannel属性吐出一个元组(因为它获取了txt1的全部,而不是获取时间节点的父级的txt1属性名。
我查看了XPath文档,并阅读了lxml教程,但无法弄清楚为什么我的动态搜索不起作用。 我需要退回到.findall()
吗? 如何使用此动态搜索获取txt1
每个值的数据?
可能有一种更Python化的方法来实现此目的,例如设置一个函数,该函数获取父级的属性[@name]
,子级的属性[@Time]
以及孙子value
的文本,但是我有还不知道该怎么做。
好的,我解决了这个问题-但解决方案仍然很难看。
我很高兴弄清楚它能得到我想要的输出。 如果有人有更清洁的方法,我希望看到它。 谢谢。
dTime=[]
dchannel = []
dvalue=[]
for df in root.xpath('//channel/Time'):
dchannel.append(df.getparent().attrib['name'])
## Iterate over attributes of time for specific channel
for attrib in df.attrib:
dTime.append(df.attrib[attrib])
## value is a child of time, and iterate
subfields = df.getchildren()
for subfield in subfields:
dvalue.append(subfield.text)
perf=DataFrame({'Channel': dchannel,'Time':dTime,'values':dvalue})
perf[:2]
Channel Time value
0 blah 2013-05-01 00:00:00 258
1 blah 2013-05-01 00:01:00 259
2 blah 2013-05-01 00:02:00 258
perf[12957:12960]
Channel Time value
12957 lir 2013-05-01 00:00:00 67
12958 lir 2013-05-01 00:01:00 67
12959 lir 2013-05-01 00:02:00 66
好极了
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.