使用lxml-python在位置添加/更新元素
我有一种情况,我想在这个位置添加一个特定的元素,如果给定的位置已经存在,则更新它。例:使用lxml-python在位置添加/更新元素,python,python-2.7,lxml,Python,Python 2.7,Lxml,我有一种情况,我想在这个位置添加一个特定的元素,如果给定的位置已经存在,则更新它。例: <items> <productid /> <product_details> <entry> <key>?</key> <value>?</value> </entry> </product_details
<items>
<productid />
<product_details>
<entry>
<key>?</key>
<value>?</value>
</entry>
</product_details>
</items>
然后它应该更新xml,因为位置1已经有entry/key和entry/value。i、 e
<items>
<productid />
<product_details>
<entry>
<key>ProductName</key>
<value>Maggi</value>
</entry>
</product_details>
</items>
产品名称
美极
如果我通过的位置为2,则应为:
<items>
<productid />
<product_details>
<entry>
<key>?</key>
<value>?</value>
</entry>
<entry>
<key>ProductName</key>
<value>Maggi</value>
</entry>
</product_details>
</items>
?
?
产品名称
美极
编辑:到目前为止,我诚实地尝试在该位置插入。因为我对Python非常陌生,所以对于如何实现这一点我有点困惑。下面的代码是我从SO获得的稍加修改的版本。例:
def to_xml(parent, xpath, value, index):
nodes = parent.xpath(xpath)
if nodes:
node = nodes[0]
else:
parts = xpath.split('/')
p = parent
for part in parts:
nodes = p.xpath(part)
if not nodes:
n = etree.XML("<%s/>" % part)
p.append(n)
p = n
else:
p = nodes[0]
node = p
node.text = str(value)
def to_xml(父级、xpath、值、索引):
nodes=parent.xpath(xpath)
如果节点:
节点=节点[0]
其他:
parts=xpath.split(“/”)
p=父母
对于部分中的部分:
nodes=p.xpath(部分)
如果不是节点:
n=etree.XML(“%part”)
p、 附加(n)
p=n
其他:
p=节点[0]
节点=p
node.text=str(值)
我自己解决了这个问题。这就是我正在做的,可能有比这更好的版本,请建议:
from lxml import etree
def add_to_xml(tree, parent, subelement, index, column_value_split):
element_found = tree.xpath("(.//" + parent + "/" + subelement + ")[" + index + "]")
if not element_found:
parent_element = tree.xpath(".//" + parent)[0]
node_element = etree.XML("<" + subelement + "/>")
parent_element.insert(int(index), node_element)
for column_value in column_value_split:
element, element_value = column_value.split("=")
if element_found:
item = element_found[0].xpath(element)[0]
item.text = element_value
else:
sub_node_element = etree.XML("<" + element + "/>")
node_element.append(sub_node_element)
sub_node_element.text = element_value
tree = etree.parse("products_list.xml")
column_name = "product_details/entry/1"
column_value = "key=ProductName;value=Maggi"
parent, subelement, index = column_name.split("/")
column_value_split = column_value.split(";")
add_to_xml(tree, parent, subelement, index, column_value_split)
从lxml导入etree
def add_to_xml(树、父元素、子元素、索引、列\u值\u拆分):
element_found=tree.xpath((./“+parent+”/“+subelement+”[“+index+”]))
如果未找到元素_:
parent_元素=tree.xpath(“./”+parent)[0]
node_element=etree.XML(“”)
父元素。插入(int(索引),节点元素)
对于列值分割中的列值:
元素,元素值=列值。拆分(“”)
如果找到元素_:
item=element\u找到[0]。xpath(element)[0]
item.text=元素值
其他:
子节点元素=etree.XML(“”)
节点\元素。追加(子节点\元素)
子节点元素文本=元素值
tree=etree.parse(“products\u list.xml”)
column\u name=“产品详细信息/entry/1”
column\u value=“key=ProductName;value=Maggi”
父元素、子元素、索引=列\u name.split(“/”)
列值分割=列值分割(“;”)
将\添加到\ xml(树、父元素、子元素、索引、列\值\拆分)
以防您需要其他解决方案。我假设您总是在修改/添加条目。此解决方案将与lxml
和包含库的电池一起使用
#import xml.etree.ElementTree as etree
from lxml import etree
def upsert_entry(parent, index, key, value):
entry_template = """
<entry>
<key>{0}</key>
<value>{1}</value>
</entry>
"""
entries = parent.findall('./entry')
# update if entry already exists.
if index <= len(entries):
entry = entries[index - 1]
entry.find('key').text = key
entry.find('value').text = value
# insert at the end (only if the index is exactly after the last entry)
elif index == len(entries) + 1:
entry = etree.fromstring(entry_template.format(key, value))
parent.append(entry)
tree = etree.parse('products_list.xml')
parent = tree.find('.//product_details')
upsert_entry(parent, 1, 'ProductName', 'Maggi')
upsert_entry(parent, 2, 'NewProductName', 'NewValue')
upsert_entry(parent, 5, 'NoAddedProductName', 'NoAddedValue')
#将xml.etree.ElementTree作为etree导入
从lxml导入etree
def upsert_条目(父项、索引、键、值):
条目\模板=“”“
{0}
{1}
"""
entries=parent.findall(“./entry”)
#如果条目已存在,则更新。
如果索引用于需要其他选项的人,则此项工作适用于我:
sig_root = etree.tostring(sig_root).replace('xxx</ds:DigestValue>',digest_keyinfo+'</ds:DigestValue>')
sig_root = etree.fromstring(sig_root)
sig_root=etree.tostring(sig_root).replace('xxx',digest_keyinfo+“”)
sig_root=etree.fromstring(sig_root)
您忘记包含您尝试过的Python代码。@Tichodroma添加了我尝试过的代码,但不确定这是否有用。我完全不知道如何实现这一点。
sig_root = etree.tostring(sig_root).replace('xxx</ds:DigestValue>',digest_keyinfo+'</ds:DigestValue>')
sig_root = etree.fromstring(sig_root)