通过元素树创建 xml 后解析时出现元素树错误
Element Tree error on parse after creating xml via element tree
为什么这段代码创建的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: not well-formed (invalid token): line 1, column 41"。
从 Firefox 我得到:"error on line 1 at column 42: Specification mandate value for attribute Price"。
xml 的第一个卡盘(当通过 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>
我完全不知所措...有什么建议吗?
注意:我不是程序员,我在玩游戏时这样做是为了好玩,所以请不要为了任何事情而对我太过苛刻...
元素名称不能包含空格。例如,您可以将出现的 '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>
元素名称中不能包含空格,例如 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'
为什么这段代码创建的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: not well-formed (invalid token): line 1, column 41"。
从 Firefox 我得到:"error on line 1 at column 42: Specification mandate value for attribute Price"。
xml 的第一个卡盘(当通过 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>
我完全不知所措...有什么建议吗?
注意:我不是程序员,我在玩游戏时这样做是为了好玩,所以请不要为了任何事情而对我太过苛刻...
元素名称不能包含空格。例如,您可以将出现的 '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>
元素名称中不能包含空格,例如 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'