我试图用树中其他子元素的文本替换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',))
这会输出错误 . 我要看的是Value子元素中的文本段落将替换为ConfigurationModel,Handing,EXWidth和EXHeight Name子元素中的Value子元素文本,如下所示:
<ConfigurationAttribute>
<Name>LongDescription</Name>
<Value> HV, XO, 59.5" x 59.5"</Value>
</ConfigurationAttribute>
以下是运行代码时收到的错误:
回溯(最近一次调用最后一次):文件“\ 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)文件“C:\ Users \ natep .RANDK \ AppData \ Local \ Programs \ Python \ Python37-32 \ lib \ xml \ etree \ ElementTree.py“,第942行,在_serialize_xml中short_empty_elements = short_empty_elements)文件”C:\ Users \ natep.RANDK \ AppData \ Local \程序\ Python \ Python37-32 \ lib \ xml \ etree \ ElementTree.py“,第942行,在_serialize_xml中short_empty_elements = short_empty_elements)文件”C:\ Users \ natep.RANDK \ AppData \ Local \ Programs \ Python \ Python37-32 \ lib \ xml \ etree \ ElementTree.py“,第942行,在_serialize_xml中short_empty_elements = short_empty_elements)[上一行重复3次]文件”C:\ Users \ natep.RANDK \ AppData \ Local \ Programs \ Python \ Python37-在_serialize中的32 \ lib \ xml \ etree \ ElementTree.py“,第939行_xml write(_escape_cdata(text))TypeError:write()参数必须是str,而不是tuple
在输出文件中,我尝试更改的Value子元素为空,没有结束标记,现在删除了过去的所有内容 .
1 回答
考虑XSLT,这是专门用于转换XML文件的专用语言 . Python的第三方模块
lxml
可以运行XSLT 1.0脚本(不是内置的etree
)并且没有单个循环就可以运行 .具体来说,XSLT脚本运行Identity Transform以按原样复制整个文档 . 然后,脚本通过使用条件XPath(兄弟到XSLT)表达式提取前面的兄弟节点并最终将文本值与逗号分隔符和所需引号连接在一起来调整最后一个Value节点 .
XSLT (另存为.xsl文件,下面将在Python中加载一个特殊的.xml文件)
XSLT Fiddle Demo
Python