如何使用Python将某些信息从文本文件复制到XML?

时间:2013-11-26 18:05:50

标签: python xml elementtree

我们会在买家购买时收到订单电子邮件;这些电子邮件以文本格式发送,包含一些相关信息和一些无关信息。我正在尝试编写一个python程序,它将读取文本,然后构建一个XML文件(使用ElementTree),我们可以将其重要到其他软件中。

不幸的是,我不太了解其中一些的正确条款,所以请忍受过长的解释。

问题在于我无法弄清楚如何使它与订单中的多个产品一起使用。该程序当前遍历每个订单并将数据放入字典中。

while file_length_dic != 0:
    #goes line by line and adds each value (and it's name) to a dictionary
    #keys are the first have a sentence followed by a distinguishing number
    for line in raw_email:
        colon_loc = line.index(':')
        end_loc = len(line)
        data_type = line[0:colon_loc] + "_" + file_length
        data_variable = line[colon_loc+2:end_loc].lstrip(' ')
        xml_dic[data_type] = data_variable
        if line.find("URL"):
            break
    file_lenght_dic -= 1

如何将此字典值转换为XML?例如,在主“JOB”元素下将有一个子元素ITEMNUMBER,然后是SALESMANN和QUANTITY。我怎样才能填写多套?

<JOB>
    <ITEM>
        <ITEMNUMBER>36322</ITEMNUMBER>
        <SALESMANN>17</SALESMANN>
        <QUANTITY>2</QUANTITY>
    </ITEM>
    <ITEM>
        <ITEMNUMBER>22388</ITEMNUMBER>
        <SALESMANN>5</SALESMANN>
        <QUANTITY>8</QUANTITY>
    </ITEM>
</JOB>

据我所知,ElementTree只会让我把数据放到第一组孩子中,但我无法想象这一定是如此。我也不知道每个订单有多少件物品;它可以是1到150之间的任何地方,程序需要轻松扩展。

我应该使用不同的库吗? lxml看起来很强大但又一次,我不知道我正在寻找什么。

2 个答案:

答案 0 :(得分:0)

这是一个简单的例子。请注意,基本的ElementTree并不相同,因此我添加了ElementTree作者的pretty print function

如果您提供输入文件和字典的实际示例,则可以更轻松地定位您的特定案例。我只是将一些数据放在字典中,以显示如何迭代它并生成一些XML。

from xml.etree import ElementTree as et

def indent(elem, level=0):
    i = "\n" + level*"  "
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for elem in elem:
            indent(elem, level+1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i

D = {36322:(17,2),22388:(5,8)}

job = et.Element('JOB')
for itemnumber,(salesman,quantity) in D.items():
    item = et.SubElement(job,'ITEMNUMBER').text = str(itemnumber)
    et.SubElement(job,'SALESMAN').text = str(salesman)
    et.SubElement(job,'QUANTITY').text = str(quantity)
indent(job)
et.dump(job)

输出:

<JOB>
  <ITEMNUMBER>36322</ITEMNUMBER>
  <SALESMAN>17</SALESMAN>
  <QUANTITY>2</QUANTITY>
  <ITEMNUMBER>22388</ITEMNUMBER>
  <SALESMAN>5</SALESMAN>
  <QUANTITY>8</QUANTITY>
</JOB>

虽然正如@alko所提到的,更结构化的XML可能是:

job = et.Element('JOB')
for itemnumber,(salesman,quantity) in D.items():
    item = et.SubElement(job,'ITEM')
    et.SubElement(item,'NUMBER').text = str(itemnumber)
    et.SubElement(item,'SALESMAN').text = str(salesman)
    et.SubElement(item,'QUANTITY').text = str(quantity)

输出:

<JOB>
  <ITEM>
    <NUMBER>36322</NUMBER>
    <SALESMAN>17</SALESMAN>
    <QUANTITY>2</QUANTITY>
  </ITEM>
  <ITEM>
    <NUMBER>22388</NUMBER>
    <SALESMAN>5</SALESMAN>
    <QUANTITY>8</QUANTITY>
  </ITEM>
</JOB>

答案 1 :(得分:0)

您的XML结构似乎对我无效。如何判断哪个salesman引用哪个itemnumber

可能你需要像

这样的东西
<JOB>
    <ITEM>
        <NUMBER>36322</NUMBER>
        <SALESMANN>17</SALESMANN>
        <QUANTITY>2</QUANTITY>
    </ITEM>
    <ITEM>
        <NUMBER>22388</NUMBER>
        <SALESMANN>5</SALESMANN>
        <QUANTITY>8</QUANTITY>
    </ITEM>
</JOB>

有关序列化技术的列表,请参阅Serialize Python dictionary to XML

dicttoxml示例:

import dicttoxml
from xml.dom.minidom import parseString

xml = dicttoxml.dicttoxml({'JOB':[{'NUMBER':36322,
                                    'QUANTITY': 2, 
                                    'SALESMANN': 17}
                                  ]}, root=False)
dom = parseString(xml)

和输出

>>> print(dom.toprettyxml())
<?xml version="1.0" ?>
<JOB type="list">
        <item type="dict">
                <SALESMANN type="int">
                        17
                </SALESMANN>
                <NUMBER type="int">
                        36322
                </NUMBER>
                <QUANTITY type="int">
                        2
                </QUANTITY>
        </item>
</JOB>