如何将表导出到xml以包含嵌套的重复元素

时间:2014-01-21 03:33:39

标签: xml

我有一张这样的表:

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;我甚至只想暗示如何解决这个问题,但我迷失在哪里开始。

感谢您提前提供任何帮助

2 个答案:

答案 0 :(得分:2)

XML的核心,在任何地方都没有预先定义的行为。

  1. 您需要根据自己的风格定义
  2. 您还需要定义一个代表您的业务逻辑的消费代码。(根据您的风格
  3. 两者都是你自己。好的,在您当前的问题中,您需要在<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>