【发布时间】:2019-01-16 06:30:58
【问题描述】:
我正在尝试将 XML 树中的值文本替换为树中其他子元素中的文本。我是 Python 新手,需要一些关于如何编写的帮助。
我的 XML 示例,其中一些元素因长度而被省略:
<SalesOrder>
<SalesOrderLines>
<SalesOrderLine>
<Item>
<LineNo>1</LineNo>
<Quantity>4.00</Quantity>
</Item>
<ConfigurationDetails>
<ConfigurationDetail>
<ConfigurationAttribute>
<Name>ConfigurationModel</Name>
<Value>HV</Value>
</ConfigurationAttribute>
<ConfigurationAttribute>
<Name>EXWidth</Name>
<Value>59.5</Value>
</ConfigurationAttribute>
<ConfigurationAttribute>
<Name>EXHeight</Name>
<Value>59.5</Value>
</ConfigurationAttribute>
<ConfigurationAttribute>
<Name>Handing</Name>
<Value>XO</Value>
</ConfigurationAttribute>
<ConfigurationAttribute>
<Name>LongDescription</Name>
<Value>This is a long paragraph of text i want to replace with
the above text for the Value sub-element</Value>
</ConfigurationAttribute>
</ConfigurationDetail>
</ConfigurationDetails>
</SalesOrderLine>
</SalesOrderLines>
</SalesOrder>
这是我第一次尝试使用 ElementTree 库的 Python 代码:
import xml.etree.ElementTree as ET
from tkinter import Tk
from tkinter.filedialog import askopenfilename, asksaveasfilename
Tk().withdraw()
file = askopenfilename()
tree = ET.parse(file)
root = tree.getroot()
def model():
for ConfigurationAttribute in root.iter('ConfigurationAttribute'):
descrip = ConfigurationAttribute.find('Name').text
model = ''
if descrip == 'ConfigurationModel':
model = ConfigurationAttribute.find('Value').text
def handing():
for ConfigurationAttribute in root.iter('ConfigurationAttribute'):
descrip = ConfigurationAttribute.find('Name').text
handing = ''
if descrip == 'Handing' and ConfigurationAttribute.find('Value') is
not None:
handing = ConfigurationAttribute.find('Value').text
def width():
for ConfigurationAttribute in root.iter('ConfigurationAttribute'):
descrip = ConfigurationAttribute.find('Name').text
width = ''
if descrip == 'EXWidth':
width = ConfigurationAttribute.find('Value').text
def height():
for ConfigurationAttribute in root.iter('ConfigurationAttribute'):
descrip = ConfigurationAttribute.find('Name').text
height = ''
if descrip == 'EXHeight':
height = ConfigurationAttribute.find('Value').text
for ConfigurationAttribute in root.iter('ConfigurationAttribute'):
descrip = ConfigurationAttribute.find('Name').text
if descrip == 'LongDescription':
model()
handing()
width()
height()
ConfigurationAttribute.find('Value').text = str(model), str(handing),
str(width), '" x ', str(height), '"'
tree.write(asksaveasfilename(defaultextension='.xml',))
这会输出错误。我正在寻找的是要替换为来自 ConfigurationModel、Handing、EXWidth 和 EXHeight Name 子元素的 Value 子元素文本的 Value 子元素中的文本段落,如下所示:
<ConfigurationAttribute>
<Name>LongDescription</Name>
<Value> HV, XO, 59.5" x 59.5"</Value>
</ConfigurationAttribute>
以下是我在运行代码时收到的错误:
Traceback(最近一次调用最后一次): 文件“\app\users\Home\natep\Documents\NP\py\PrestoParse.py”,第 59 行,在 tree.write(asksaveasfilename(defaultextension='.xml',)) 文件“C:\Users\natep.RANDK\AppData\Local\Programs\Python\Python37-32\lib\xml\etree\ElementTree.py”,第 777 行,写入 short_empty_elements=short_empty_elements) _serialize_xml 中的文件“C:\Users\natep.RANDK\AppData\Local\Programs\Python\Python37-32\lib\xml\etree\ElementTree.py”,第 942 行 short_empty_elements=short_empty_elements) _serialize_xml 中的文件“C:\Users\natep.RANDK\AppData\Local\Programs\Python\Python37-32\lib\xml\etree\ElementTree.py”,第 942 行 short_empty_elements=short_empty_elements) _serialize_xml 中的文件“C:\Users\natep.RANDK\AppData\Local\Programs\Python\Python37-32\lib\xml\etree\ElementTree.py”,第 942 行 short_empty_elements=short_empty_elements) [上一行再重复 3 次] _serialize_xml 中的文件“C:\Users\natep.RANDK\AppData\Local\Programs\Python\Python37-32\lib\xml\etree\ElementTree.py”,第 939 行 写(_escape_cdata(文本)) TypeError: write() 参数必须是 str,而不是 tuple
在输出文件中,我尝试更改的 Value 子元素是空的,没有结束标记,并且现在删除了所有超过它的内容。
【问题讨论】:
-
欢迎来到 SO!你看到了什么确切的错误? (通常,如果您的问题涉及错误,最好将错误包含在您的问题中。)
-
你可以使用像
lxml这样的非内置库吗?此外,XML 中存在拼写错误 (SalesOderLine) 和未关闭的节点 (ConfigurationDetail)。 -
感谢您抽出宝贵时间查看此内容。我已包含错误并编辑了 XML 中的拼写错误并添加到 ConfigurationDetail 的结束标记。我可以使用
lxml,如果这是我想要在这里实现的更好的解决方案。
标签: python xml python-3.x xml-parsing elementtree