Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用lxml-python在位置添加/更新元素_Python_Python 2.7_Lxml - Fatal编程技术网

使用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)