将 elem.attrib 的多个值添加到变量中
adding multiple values of elem.attrib into a variable
最近开始使用 Python 和 ElementTree 来实现一些非常具体的目标。我想我快到了,但有一件事我还不能完全解决。我正在查询一个 xml 文件并提取相关数据 - 然后将该数据放入一个 csv 文件中。一切正常,但问题是 elem.attrib["text"] 实际上 returns 多行 - 当我将它放入变量并导出到 csv 时,它只导出第一行- 下面是我正在使用的代码...
import os
import csv
import xml.etree.cElementTree as ET
path = "/share/new"
c = csv.writer(open("/share/redacted.csv", "wb"))
c.writerow(["S","R","T","R2","R3"])
for filename in os.listdir(path):
if filename.endswith('.xml'):
fullname = os.path.join(path, filename)
tree = ET.ElementTree(file=(fullname))
for elem in tree.iterfind('PropertyList/Property[@name="Sender"]'):
c1 = elem.attrib["value"]
for elem in tree.iterfind('PropertyList/Property[@name="Recipient"]'):
c2 = elem.attrib["value"]
for elem in tree.iterfind('PropertyList/Property[@name="Date"]'):
c3 = elem.attrib["value"]
for elem in tree.iterfind('ChildContext/ResponseList/Response/TextualAnalysis/ExpressionList/Expression/Match'):
c4 = elem.attrib["textView"]
for elem in tree.iterfind('ChildContext/ResponseList/Response/TextualAnalysis/ExpressionList/Expression/Match/Matched'):
c5 = elem.attrib["text"]
print elem.attrib["text"]
print c5
c.writerow([(c1),(c2),(c3),(c4),(c5)])
最重要的部分就在底部附近 - print elem.atrrib["text"] 的输出是:
Apples
Bananas
'print c5' 的输出是相同的(只是要清楚,Apples 和 Bananas 在不同的行上)
但是,将 c5 输出到 csv 只会输出第一行,因此 csv 中只会出现苹果。
我希望这是有道理的 - 我需要做的是将 Apples 和 Bananas 都输出到 csv(最好在同一个单元格中)。下面是 Python 2.7 开发中的,但理想情况下我需要它在 2.6 中工作(我意识到 iterfind 不在 2.6 中 - 我已经有 2 个版本的代码)
我会 post xml 但它有点像野兽。 - 根据此处评论中的建议,已清理 XML.
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Context>
<PropertyList duplicates="true">
<Property name="Sender" type="string" value="S:demo1@no-one.local"/>
<Property name="Recipient" type="string" value="RPFD:no-one.local"/>
<Property name="Date" type="string" value="Tue, 4 Aug 2015 13:24:16 +0100"/>
</PropertyList>
<ChildContext>
<ResponseList>
<Response>
<Description>
<Arg />
<Arg />
</Description>
<TextualAnalysis version="2.0">
<ExpressionList>
<Expression specified=".CLEAN.(Apples)" total="1" >
<Match textView="Body" truncated="false">
<Surrounding text="..."/>
<Surrounding text="How do you like them "/>
<Matched cleaned="true" text="Apples " type="expression"/>
<Surrounding text="???????? "/>
<Surrounding text="..."/>
</Match>
</Expression>
</ExpressionList>
</TextualAnalysis>
</Response>
</ResponseList>
</ChildContext>
<ChildContext>
<ResponseList>
<Response>
<Description>
<Arg />
<Arg />
</Description>
<TextualAnalysis version="2.0">
<ExpressionList>
<Expression specified=".CLEAN.(Bananas)" total="1" >
<Match textView="Attach" truncated="false">
<Surrounding text="..."/>
<Surrounding text="Also I don't like... "/>
<Matched cleaned="true" text="Bananas " type="expression"/>
<Surrounding text="!!!!!!! "/>
<Surrounding text="..."/>
</Match>
</Expression>
</ExpressionList>
</TextualAnalysis>
</Response>
</ResponseList>
</ChildContext>
</Context>
以下内容会将所有文本元素连接在一起,并将它们放在单独的行中在您的 CSV 中的同一单元格 中。您可以将 '\n' 分隔符更改为 ' ' 或 ',' 以将它们放在同一行。 但是,您的其他一些东西可能仍然存在问题 -- 您那里没有嵌套循环,我不太明白您想要完成什么,所以也许您也有不止一个其他的东西。不管怎样:
c5 = []
for elem in tree.iterfind('ChildContext/ResponseList/Response/TextualAnalysis/ExpressionList/Expression/Match/Matched'):
c5.append(elem.attrib["text"])
c.writerow([c1, c2, c3, c4, '\n'.join(c5)])
最近开始使用 Python 和 ElementTree 来实现一些非常具体的目标。我想我快到了,但有一件事我还不能完全解决。我正在查询一个 xml 文件并提取相关数据 - 然后将该数据放入一个 csv 文件中。一切正常,但问题是 elem.attrib["text"] 实际上 returns 多行 - 当我将它放入变量并导出到 csv 时,它只导出第一行- 下面是我正在使用的代码...
import os
import csv
import xml.etree.cElementTree as ET
path = "/share/new"
c = csv.writer(open("/share/redacted.csv", "wb"))
c.writerow(["S","R","T","R2","R3"])
for filename in os.listdir(path):
if filename.endswith('.xml'):
fullname = os.path.join(path, filename)
tree = ET.ElementTree(file=(fullname))
for elem in tree.iterfind('PropertyList/Property[@name="Sender"]'):
c1 = elem.attrib["value"]
for elem in tree.iterfind('PropertyList/Property[@name="Recipient"]'):
c2 = elem.attrib["value"]
for elem in tree.iterfind('PropertyList/Property[@name="Date"]'):
c3 = elem.attrib["value"]
for elem in tree.iterfind('ChildContext/ResponseList/Response/TextualAnalysis/ExpressionList/Expression/Match'):
c4 = elem.attrib["textView"]
for elem in tree.iterfind('ChildContext/ResponseList/Response/TextualAnalysis/ExpressionList/Expression/Match/Matched'):
c5 = elem.attrib["text"]
print elem.attrib["text"]
print c5
c.writerow([(c1),(c2),(c3),(c4),(c5)])
最重要的部分就在底部附近 - print elem.atrrib["text"] 的输出是:
Apples
Bananas
'print c5' 的输出是相同的(只是要清楚,Apples 和 Bananas 在不同的行上)
但是,将 c5 输出到 csv 只会输出第一行,因此 csv 中只会出现苹果。
我希望这是有道理的 - 我需要做的是将 Apples 和 Bananas 都输出到 csv(最好在同一个单元格中)。下面是 Python 2.7 开发中的,但理想情况下我需要它在 2.6 中工作(我意识到 iterfind 不在 2.6 中 - 我已经有 2 个版本的代码)
我会 post xml 但它有点像野兽。 - 根据此处评论中的建议,已清理 XML.
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Context>
<PropertyList duplicates="true">
<Property name="Sender" type="string" value="S:demo1@no-one.local"/>
<Property name="Recipient" type="string" value="RPFD:no-one.local"/>
<Property name="Date" type="string" value="Tue, 4 Aug 2015 13:24:16 +0100"/>
</PropertyList>
<ChildContext>
<ResponseList>
<Response>
<Description>
<Arg />
<Arg />
</Description>
<TextualAnalysis version="2.0">
<ExpressionList>
<Expression specified=".CLEAN.(Apples)" total="1" >
<Match textView="Body" truncated="false">
<Surrounding text="..."/>
<Surrounding text="How do you like them "/>
<Matched cleaned="true" text="Apples " type="expression"/>
<Surrounding text="???????? "/>
<Surrounding text="..."/>
</Match>
</Expression>
</ExpressionList>
</TextualAnalysis>
</Response>
</ResponseList>
</ChildContext>
<ChildContext>
<ResponseList>
<Response>
<Description>
<Arg />
<Arg />
</Description>
<TextualAnalysis version="2.0">
<ExpressionList>
<Expression specified=".CLEAN.(Bananas)" total="1" >
<Match textView="Attach" truncated="false">
<Surrounding text="..."/>
<Surrounding text="Also I don't like... "/>
<Matched cleaned="true" text="Bananas " type="expression"/>
<Surrounding text="!!!!!!! "/>
<Surrounding text="..."/>
</Match>
</Expression>
</ExpressionList>
</TextualAnalysis>
</Response>
</ResponseList>
</ChildContext>
</Context>
以下内容会将所有文本元素连接在一起,并将它们放在单独的行中在您的 CSV 中的同一单元格 中。您可以将 '\n' 分隔符更改为 ' ' 或 ',' 以将它们放在同一行。 但是,您的其他一些东西可能仍然存在问题 -- 您那里没有嵌套循环,我不太明白您想要完成什么,所以也许您也有不止一个其他的东西。不管怎样:
c5 = []
for elem in tree.iterfind('ChildContext/ResponseList/Response/TextualAnalysis/ExpressionList/Expression/Match/Matched'):
c5.append(elem.attrib["text"])
c.writerow([c1, c2, c3, c4, '\n'.join(c5)])