1

好的,所以我有以下 .csv 文件,其中包含:

AAC=1|1|1,AAK=1|2|8

我想将该文件写入以下 .xml 文件:

<html>
  <A>
    <B>
      <C>
        <D>
          <TYPE>
            <NUMBER>7297</NUMBER>
            <DATA />
          </TYPE>
          <TYPE>
            <NUMBER>7721</NUMBER>
            <DATA>AAC=7|3|8,ABC=1|3|5,DAK=5|1|3,FFK=33</DATA>
          </TYPE>
        </D>
      </C>
    </B>
  </A>
</html>

我想专门将其写入 7721 下的部分,因此更新后的 .xml 文件如下所示:

<html>
  <A>
    <B>
      <C>
        <D>
          <TYPE>
            <NUMBER>7297</NUMBER>
            <DATA />
          </TYPE>
          <TYPE>
            <NUMBER>7721</NUMBER>
            <DATA>AAC=1|1|1,AAK=1|2|8,ABC=1|3|5,DAK=5|1|3,FFK=33</DATA>
          </TYPE>
        </D>
      </C>
    </B>
  </A>
</html>

如您所见,如果 .csv 和 .xml 上都已存在该键,那么它只会更新 .xml 文件上的值,但如果 .csv 文件上的键和值都不存在于 . xml 文件,然后它将这些键和值添加到 .xml 文件中。

到目前为止我的代码:

element = etree.fromstring(xmlData)

# Find all the TYPE with NUMBER=7721 and DATA
optype_nodes = element.xpath("//TYPE[NUMBER='7721' and DATA]")

for t in optype_nodes:
    d = t.find('DATA')
    d.text = 'csvdata'
print etree.tostring(element)

刚结束导入所有 .csv 内容并完全替换 .xml 内容。

谢谢!

4

3 回答 3

1

首先,让我们编写一个函数,将您的一个字符串(来自 csv 或 xml)转换为字典:

def string_to_dict(string):
    # Split the string on commas
    list_of_entries = string.split(',')
    # Each of these entries needs to be split on '='
    # We'll use a list comprehension
    list_of_split_entries = map(lambda e: e.split('='), list_of_entries)
    # Now we have a list of (key, value) pairs.  We can pass this
    # to the dict() function to get a dictionary out of this, and 
    # that's what we want to return
    return dict(list_of_split_entries)

现在我们要获取 csv 数据和 xml 数据的字典:

csv_dict = string_to_dict(csv_data)
# csv_dict = {'AAK': '1|2|8', 'AAC': '1|1|1'}
xml_dict = string_to_dict(d.text)
# xml_dict = {'ABC': '1|3|5', 'FFK': '33', 'AAC': '7|3|8', 'DAK': '5|1|3'}

使用更新函数,我们可以将 csv_dict 中的值添加到 xml_dict,覆盖它们相同的地方:

xml_dict.update(csv_dict)
# xml_dict = {'ABC': '1|3|5', 'FFK': '33', 'AAC': '1|1|1', 'AAK': '1|2|8', 'DAK': '5|1|3'}

现在我们需要xml_dict回到一个字符串。执行此操作的简单方法是:

# Let's get a list of key=value strings
list_of_items = ['%s=%s' % (k, v) for k, v in xml_dict.iteritems()]
# Now join those items together
new_xml_text = ','.join(list_of_items)
d.text = new_xml_text

如果你想让它们保持排序,你可以这样做:

d.text = ','.join('%s=%s' % (k, xml_dict[k]) for k in sorted(xml_dict.keys()))
于 2012-07-27T16:50:57.503 回答
0

我不确定这对您是否可行,这意味着:如果您绑定到问题中包含的 xml 文件结构。如果您可以自由选择结构,您可以利用 XML 并像这样存储数据:

<TYPE>
   <NUMBER>7297</NUMBER>
   <DATA />
</TYPE>
<TYPE>
  <NUMBER>7721</NUMBER>
  <DATA>
    <AAC>1|1|1</AAC>
    <AAK>1|2|8</AAK>
    <ABC>1|3|5</ABC>
    <DAK>5|1|3</DAK>
  <DATA>
</TYPE>

这样,您可以更轻松地更新特定值并通过 xpath 访问它们。要为 xml 结构准备检索到的 csvStr,您可以使用 split():

lst = csvStr.split(',')
for dataStr in lst:
    data = dataStr.split('=')
    #data[0]: var name, data[1]: var value

希望这会有所帮助。

于 2012-07-27T16:38:45.913 回答
0

所以,想更新d.text。一种方法是转换为字典并更新,然后写回 d.text。当您将其写回时,请确保您拥有正确的 csv 订单。我看是字母表。确保是这种情况。因为我们正在转换为字典然后更新,所以我们冒着改变顺序的风险。

def get_csv_dict(csv_line):

    return dict([(k,v) for k, v in map(lambda x: x.split('='), csv_line)])

contents = get_csv_dict(d.text)
required_contents = get_csv_dict(csvdata)
contents.update(required_contents)

然后做

>>> temp = []
>>> for key in sorted(contents.keys()):
...     temp.append(key + '=' + contents[key])
... 
>>> d.text = ",".join(temp)

你会发现d.text你想要的更新。

于 2012-07-27T16:47:06.083 回答