我有一张这样的表:
Award | Name | Amount
Gold | John | $5
Gold | Karen | $5
Gold | Clyde | $4
Silver | Blake | $3
我正在寻找像这样的xml输出:(这样第1列中的匹配数据被视为一个元素,其相应的数据被视为重复的兄弟元素
<prize>
<award>gold</award>
<awardee>
<name>John</name>
<amount>$5</amount>
</awardee>
<awardee>
<name>Karen</name>
<amount>$4</amount>
</awardee>
<awardee>
<name>Clyde</name>
<amount>$3/amount>
</awardee>
</prize>
<prize>
<award>silver</award>
...
该表源自访问数据库,并作为csv导出。我已经尝试将此模式导入excel并导出为xml,但抛出的错误与&#34;由于列表中的列表而无法导出xml。&#34;我甚至只想暗示如何解决这个问题,但我迷失在哪里开始。
感谢您提前提供任何帮助
答案 0 :(得分:2)
XML的核心,在任何地方都没有预先定义的行为。
两者都是你自己。好的,在您当前的问题中,您需要在<prize>
周围放置一个父元素。否则,它会将xml作为基本规则抛出错误,从而避免多个根元素。 (它应该包含一个根元素,只有一个。)
尝试在从访问权限或某些内容导出时注意这一点。如果您可以控制访问数据库,则可以选择SELECT CONCAT("<ROOT_ELEMENT>", YOUR DATA, "</ROOT_ELEMENT>")
之类的查询...或者,在从excel导出之前,添加根元素并在结尾处关闭它。您需要以某种方式添加至少在将数据插入数据库时包装的根元素。
答案 1 :(得分:2)
如果您熟悉Python,则可能需要查看lxml模块。鉴于您的数据位于my_data.csv
(逗号分隔值)并且在示例中具有标题行,此代码应该可以解决问题(使用Python 2.7进行测试,但可能适用于大多数Python版本)。 / p>
from lxml import etree
from itertools import groupby
import csv
with open('my_data.csv') as data_file:
reader = csv.DictReader(data_file)
f = lambda x: x['Award']
data = sorted(list(reader), key=f)
root = etree.Element('root')
for k, g in groupby(data, key=f):
prize = etree.SubElement(root, 'prize')
award = etree.SubElement(prize, 'award')
award.text = k
for entry in g:
awardee = etree.SubElement(prize, 'awardee')
name = etree.SubElement(awardee, 'name')
name.text = entry['Name']
amount = etree.SubElement(awardee, 'amount')
amount.text = entry['Amount']
with open('my_data.xml', 'wb') as out_file:
out_file.write(etree.tostring(root, pretty_print=True))
输出保存到my_data.xml
,看起来像你想要的(带有额外的根标签)。
<root>
<prize>
<award>Gold</award>
<awardee>
<name>John</name>
<amount>$5</amount>
</awardee>
<awardee>
<name>Karen</name>
<amount>$5</amount>
</awardee>
<awardee>
<name>Clyde</name>
<amount>$4</amount>
</awardee>
</prize>
<prize>
<award>Silver</award>
<awardee>
<name>Blake</name>
<amount>$3</amount>
</awardee>
</prize>
</root>