Потерял в XML и Python - PullRequest
       10

Потерял в XML и Python

1 голос
/ 30 января 2012

Привет! Я начал изучать python и хочу использовать его, чтобы что-то сделать с XML-файлом.

Я искал информацию о лучшем курсе, которому нужно следовать, но, честно говоря, я немного растерялся.Существует так много способов манипулирования файлами XML, как ElementTree, lxml, minidom и т. Д. И т. Д.Может ли кто-нибудь указать мне правильное направление?Или укажите мне код, который я могу обернуть вокруг.Я начал экспериментировать с lxml, но больше не печатал все элементы.

Вот что я пытаюсь сделать:

  1. Чтение строки из файла csv,Загрузите в Label и FullPath.
  2. Просмотрите файл XML для ITEM с указанием FullPath
  3. Измените FLAG1 для этого элемента на TRUE
  4. Измените FLAG2 и FLAG3 для этого элемента наFALSE
  5. Измените Метку для этого ПУНКТА на Метку из файла CSV.
  6. Запишите new.xml

Ниже приведена моя структура xml.Две записи ниже повторяются, как 10000 раз в файле.

<ThisIsMyData>
  <ITEM>
    <Number>0</Number>
    <Flag1>TRUE</Flag1>
    <Flag2>FALSE</Flag2>  
    <Flag3>FALSE</Flag3>
    <Label>RED</Label> <<-2- After finding 1 I need to change THIS(only this)
    <Path>C:\\test\\</Path> <-1- I need to find this 
    <file>test.png</file>
  </ITEM>
  <ITEM>
    <Number>1</Number>
    <Flag1>TRUE</Flag1>
    <Flag2>FALSE</Flag2>
    <Flag3>FALSE</Flag3>
    <Label>Blue</Label>
    <Path>c:\\test\\test2\\</Path>
    <file>blue.png</file>
  </ITEM>
 </ThisIsMyData>

Итак, у меня есть ROOT: затем много элементов:.У каждого из них есть 7 SubElements.

Вот так выглядит мой CSV-файл и мне нужен мой вывод: CSV-файл:

  Label;FullPath
  YELLOW;C:\\test\\test.png
  YELLOW;c:\\test\\test2\\blue.png

 <ThisIsMyData>
  <ITEM>
    <Number>0</Number>
    <Flag1>FALSE</Flag1>
    <Flag2>FALSE</Flag2>
    <Flag3>TRUE</Flag3>
    <Label>YELLOW</Label>
    <Path>C:\\test\\</Path>
    <file>test.png</file>
  </ITEM>
  <ITEM>
    <Number>1</Number>
    <Flag1>FALSE</Flag1>
    <Flag2>FALSE</Flag2>
    <Flag3>TRUE</Flag3>
    <Label>YELLOW</Label>
    <Path>c:\\test\\test2\\</Path>
    <file>blue.png</file>
  </ITEM>
 </ThisIsMyData>

Вставить ссылку в случае, если макет испорченup:

http://pastebin.com/embed_js.php?i=QEx2ZGuY

Я пытаюсь ElementTree прямо сейчас, используя этот пример: http://pymotw.com/2/xml/etree/ElementTree/parse.html. Мне удалось найти в XML определенное имя элемента и распечатать содержимое,Но я все еще не вижу способа найти соответствующий элемент на том же уровне.

from xml.etree import ElementTree
with open('mydata.xml', 'rt') as f:
    tree = ElementTree.parse(f)
#    filelist = ElementTree.ElementTree.find()
for node in tree.findall('.//file'):
    FileName = node.tag, node.text
    print FileName      

Вывод:

('file', 'test.png')
('file', 'blue.png')

Ответы [ 3 ]

1 голос
/ 30 января 2012

Вот краткий пример того, как сделать то, что, я думаю, вы хотите, используя lxml.etree и xpath.

from cStringIO import StringIO
from lxml import etree

xmlfile = StringIO("""
<ThisIsMyData>
  <ITEM>
    <Number>0</Number>
    <Flag1>TRUE</Flag1>
    <Flag2>FALSE</Flag2>  
    <Flag3>FALSE</Flag3>
    <Label>RED</Label>
    <Path>C:\\test\\</Path>
    <file>test.png</file>
  </ITEM>
  <ITEM>
    <Number>1</Number>
    <Flag1>TRUE</Flag1>
    <Flag2>FALSE</Flag2>
    <Flag3>FALSE</Flag3>
    <Label>Blue</Label>
    <Path>c:\\test\\test2\\</Path>
    <file>blue.png</file>
  </ITEM>
 </ThisIsMyData>
""".strip())

datafile = StringIO("""
Label;FullPath
YELLOW;C:\\test\\test.png
YELLOW;c:\\test\\test2\\blue.png
""".strip())

# Read "csv". Simple, no error checking, skip first line.
filenameToLabel = {}
for l,f in (x.strip().split(';') for x in datafile.readlines()[1:]):
  filenameToLabel[f] = l

def first(seq,default=None):
  """xpath helper function"""
  for item in seq:
    return item
  return None

doc = etree.XML(xmlfile.read())

for item in doc.xpath('//ITEM'):
  item_filename = first(item.xpath('./Path/text()'),'').strip() + first(item.xpath('./file/text()'),'').strip()
  label = filenameToLabel.get(item_filename)
  if label is not None:
    first(item.xpath('./Flag1')).text = 'TRUE'
    first(item.xpath('./Flag2')).text = 'FALSE'
    first(item.xpath('./Flag3')).text = 'FALSE'
    first(item.xpath('./Label')).text = label

print etree.tostring(doc)

Выход

<ThisIsMyData>
  <ITEM>
    <Number>0</Number>
    <Flag1>TRUE</Flag1>
    <Flag2>FALSE</Flag2>
    <Flag3>FALSE</Flag3>
    <Label>YELLOW</Label>
    <Path>C:\test\</Path>
    <file>test.png</file>
  </ITEM>
  <ITEM>
    <Number>1</Number>
    <Flag1>TRUE</Flag1>
    <Flag2>FALSE</Flag2>
    <Flag3>FALSE</Flag3>
    <Label>YELLOW</Label>
    <Path>c:\test\test2\</Path>
    <file>blue.png</file>
  </ITEM>
</ThisIsMyData>
0 голосов
/ 30 января 2012

Я нахожу, что Beautiful Soup и его сестра, Beautiful Stone Soup , имеют действительно хорошую, краткую документацию, основанную на примерах, которая пригодится для погружения и опробования на реальных примерах.

Но я также слышал, что ElementTree считается некоторыми золотым стандартом в питоне.

0 голосов
/ 30 января 2012

Прежде всего используйте модуль python csv , чтобы получить данные из файла csv. Разделение строк будет хорошо работать, если данные не велики.

Чем создать свой xml используя etree.XML.

пример:

>>>from lxml import etree
>>> csv_value = 'C:\\test\\'
>>> st = '<document>'+'<Flag1>FALSE</Flag1>' + '<Flag2>FALSE</Flag2>'+'<Path>' + csv_value + '</Path>' + '</document>'
>>> tree = etree.XML(st)
>>> etree.tostring(tree)
'<document><Flag1>FALSE</Flag1><Flag2>FALSE</Flag2><Path>C:\\test\\</Path></document>'

Извлечение csv_value предоставлено вам в качестве упражнения.

Также взгляните на этот вопрос .

...