通过元素树

时间:2017-01-01 03:57:30

标签: python xml parsing xml-parsing elementtree

为什么这个代码创建的xml不能被python解析或读取?

我有一大堆编写xml文件的代码:

idlist = list(set([d['type'] for d in List]))                   ##create list of all ID numbers
idlist.sort()
root = ET.Element("MarketData")
for i in idlist:                                                ##iterate over every ID number
    doc = ET.SubElement(root, 'Item', typeID=str(i))            ##create child for current ID number
    tList = list(filter(lambda x: x['type'] == i, List))        ##make a list of all orders for current ID
    sList = list(filter(lambda x: x['buy'] == False, tList))    ##create list of only sell orders
    bList = list(filter(lambda x: x['buy'] == True, tList))     ##create list of only by orders
    spl = list([d['price'] for d in sList])                     ##create list of sell prices
    bpl = list([d['price'] for d in bList])                     ##create list of buy prices
    if not spl:                                                 ##null case
        spl = [-1]
    if not bpl:                                                 ##null case
        bpl = [-1]
    sp = min(spl)                                               ##find min sell price
    bp = max(bpl)                                               ##find max buy price
    ET.SubElement(doc, 'Sell Price').text = str(sp)             ##write sell price to child as string under new sub-element
    ET.SubElement(doc, 'Buy Price').text = str(bp)              ##write buy price to branch as string under new sub-element
tree = ET.ElementTree(root)
tree.write("MarketData.xml")                                    ##write xml tree to final xml file

它执行正常,我的测试代码使用相同的xml逻辑写入一个完全可读的文件但是当我使用这个代码创建一个文件时,它是不可读的,不能由ElementTree解析。

从python我得到:" xml.etree.ElementTree.ParseError:格式不正确(无效令牌):第1行,第41栏和第34页。

从Firefox我得到:"第42行第1行的错误:属性价格"的规范授权值。

xml的第一个chuck(通过np ++打开时)是:

<MarketData><Item typeID="18"><Sell Price>64.92</Sell Price><Buy Price>53.31</Buy Price></Item><Item typeID="19"><Sell Price>36999.99</Sell Price><Buy Price>3502.03</Buy Price></Item>

我完全失去了......有什么建议吗?

注意:我不是一个程序员,我在玩游戏时这样做是为了好玩,所以请不要因为任何事情而殴打我......

2 个答案:

答案 0 :(得分:3)

您不能在其中包含带空格的元素名称,例如Sell Price。诸如<Sell Price>(或像<Sell Price />之类的空元素标记)之类的开始标记未完成。它被解释为具有属性Sell但没有赋值的元素Price。这是非法的。

不幸的是,ElementTree允许您创建出现此错误的错误输出。这是一个小型演示(使用Python 2.7.13测试):

import xml.etree.ElementTree as ET

root = ET.Element("root")
ET.SubElement(root, 'Sell Price')
print ET.tostring(root)

此程序输出<root><Sell Price /></root>,其格式不正确。

如果使用lxml而不是ElementTree,则会得到正确的行为(抛出异常):

from lxml import etree as ET

root = ET.Element("root")
ET.SubElement(root, 'Sell Price')
print ET.tostring(root)

结果:

Traceback (most recent call last):
  File "error.py", line 6, in <module>
    ET.SubElement(root, 'Sell Price')
  File "src\lxml\lxml.etree.pyx", line 3112, in lxml.etree.SubElement (src\lxml\lxml.etree.c:75599)
  File "src\lxml\apihelpers.pxi", line 183, in lxml.etree._makeSubElement (src\lxml\lxml.etree.c:16962)
  File "src\lxml\apihelpers.pxi", line 1626, in lxml.etree._tagValidOrRaise (src\lxml\lxml.etree.c:32556)
ValueError: Invalid tag name u'Sell Price'

答案 1 :(得分:2)

元素名称不能包含空格。例如,您可以使用“Buy_Price”替换“Buy Price”的出现次数。此版本的文件将成功打开。

<MarketData>
<Item typeID="18">
<Sell_Price>64.92</Sell_Price>
<Buy_Price>53.31</Buy_Price>
</Item>
<Item typeID="19">
<Sell_Price>36999.99</Sell_Price>
<Buy_Price>3502.03</Buy_Price>
</Item>
</MarketData>