2014-10-23 3 views
1

특정 위치에 특정 요소를 추가하고 주어진 위치에 이미있는 경우 업데이트하려는 상황이 있습니다. 예 :lxml python을 사용하여 위치에 요소 추가/업데이트

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

지금 전직 말할 : 나는 1로 위치를 전달하고 키와 값에 값을 추가하려면,

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

그런 다음이 XML을 업데이트해야합니다 고려 항목이 있기 때문에/& 위치/항목의 값/키가 이미 있습니다. 나는 위치로 2를 전달하는 경우 즉,

<items> 
    <productid /> 
    <product_details> 
     <entry> 
      <key>ProductName</key> 
      <value>Maggi</value> 
     </entry> 
    </product_details> 
</items> 

은 다음과 같아야합니다

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

편집 : 그래서 지금까지 내가 정직하게 노력 어떤 위치에 삽입된다. 필자는 파이썬을 처음 접했기 때문에 이것을 달성하는 방법에 대해 혼란스러워합니다. 아래의 코드는 내가 가지고있는 것의 약간 수정 된 버전입니다. 예 :

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

시도한 파이썬 코드를 포함하는 것을 잊었습니다. –

+0

@Tichodroma, 내가 시도한 코드를 추가했지만 도움이 될지 확신하지 못했습니다. 나는 이것을 달성하는 방법에 대해 완전히 확신하지 못합니다. –

답변

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

다른 해결책이 필요한 경우. 나는 당신이 항상 항목을 수정/추가하고 있다고 가정하고 있습니다. 이 솔루션은 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') 
관련 문제