【问题标题】:Add / update elements at position using lxml python使用lxml python在位置添加/更新元素
【发布时间】:2014-10-23 08:19:20
【问题描述】:

我有一种情况,我想在该位置添加一个特定元素,如果给定位置已经存在则更新。例如:

<items>
   <productid />
   <product_details>
       <entry>
           <key>?</key>
           <value>?</value>
       </entry>
   </product_details>
</items>

现在对前任说:我将位置作为 1 传递,并希望将值添加到 Key 和 Value,考虑

parent = product_details
position = 1
key = ProductName
value = Maggi

然后它应该更新 xml,因为位置 1 已经有条目/键和条目/值。即,

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

【问题讨论】:

  • 您忘记包含您尝试过的 Python 代码。
  • @Tichodroma,添加了我尝试过的代码,但不确定这是否会有所帮助。我完全不确定如何实现这一目标。

标签: python python-2.7 lxml


【解决方案1】:

我自己解决了这个问题。所以这就是我正在做的,可能有比这更好的版本,请建议:

  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)

【讨论】:

    【解决方案2】:

    以防万一您需要其他解决方案。我假设您总是在修改/添加条目。此解决方案适用于 lxml 和包含的电池 xml.etree.ElementTree 库。

    #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')
    

    【讨论】:

      【解决方案3】:

      对于需要其他选择的人,这对我有用:

      sig_root = etree.tostring(sig_root).replace('xxx</ds:DigestValue>',digest_keyinfo+'</ds:DigestValue>')
      sig_root = etree.fromstring(sig_root)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-29
        • 1970-01-01
        • 1970-01-01
        • 2020-05-29
        • 1970-01-01
        相关资源
        最近更新 更多