2015-08-05 5 views
0

Начал играть с Python и ElementTree совсем недавно, чтобы добиться чего-то определенного. Я почти там, я думаю, но есть одна вещь, которую я не могу решить. Я запрашиваю xml-файл и оттягиваю соответствующие данные, а затем помещаю эти данные в файл csv. Все это работает, но проблема в том, что elem.attrib ["text"] фактически возвращает несколько строк - когда я помещал его в переменную переменную и экспортировал в csv, она экспортирует только первую строку - ниже используется код, который я использую ...добавление нескольких значений elem.attrib в переменную

import os 
import csv 

import xml.etree.cElementTree as ET 

path = "/share/new" 

c = csv.writer(open("/share/redacted.csv", "wb")) 

c.writerow(["S","R","T","R2","R3"]) 


for filename in os.listdir(path): 
    if filename.endswith('.xml'): 
      fullname = os.path.join(path, filename) 
      tree = ET.ElementTree(file=(fullname)) 
      for elem in tree.iterfind('PropertyList/Property[@name="Sender"]'): 
        c1 = elem.attrib["value"] 
      for elem in tree.iterfind('PropertyList/Property[@name="Recipient"]'): 
        c2 = elem.attrib["value"] 
      for elem in tree.iterfind('PropertyList/Property[@name="Date"]'): 
        c3 = elem.attrib["value"] 
      for elem in tree.iterfind('ChildContext/ResponseList/Response/TextualAnalysis/ExpressionList/Expression/Match'): 
        c4 = elem.attrib["textView"] 
      for elem in tree.iterfind('ChildContext/ResponseList/Response/TextualAnalysis/ExpressionList/Expression/Match/Matched'): 
        c5 = elem.attrib["text"] 
        print elem.attrib["text"] 
        print c5 
      c.writerow([(c1),(c2),(c3),(c4),(c5)]) 

самая важная часть в непосредственной близости от дна - выход из печати elem.atrrib [ «текст»] является:

Apples 
Bananas 

выход «печати c5» является то же самое (просто ясно, что это яблоки и бананы на отдельных линиях)

Но, выводя c5 только в csv выводит первую строку, и поэтому в csv появляются только Яблоки.

Надеюсь, это имеет смысл - то, что мне нужно сделать, - это выводить как яблоки, так и бананы в csv (желательно в той же ячейке). Ниже в Python 2.7 в разработке, но в идеале мне нужно, чтобы он работал в версии 2.6 (я понимаю, что iterfind не в 2.6 - у меня уже есть 2 версии кода)

Я бы опубликовал xml, но это немного зверь. - В соответствии с предложением в комментариях здесь приведен очищенный XML.

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> 
<Context> 
    <PropertyList duplicates="true"> 
     <Property name="Sender" type="string" value="S:[email protected]"/> 
     <Property name="Recipient" type="string" value="RPFD:no-one.local"/> 
     <Property name="Date" type="string" value="Tue, 4 Aug 2015 13:24:16 +0100"/> 
    </PropertyList> 
    <ChildContext> 
     <ResponseList> 
      <Response> 
       <Description> 
        <Arg /> 
        <Arg /> 
       </Description> 
       <TextualAnalysis version="2.0"> 
        <ExpressionList> 
         <Expression specified=".CLEAN.(Apples)" total="1" > 
          <Match textView="Body" truncated="false"> 
           <Surrounding text="..."/> 
           <Surrounding text="How do you like them "/> 
           <Matched cleaned="true" text="Apples " type="expression"/> 
           <Surrounding text="???????? "/> 
           <Surrounding text="..."/> 
          </Match> 
         </Expression> 
        </ExpressionList> 
       </TextualAnalysis> 
      </Response> 
     </ResponseList> 
    </ChildContext> 
    <ChildContext> 
     <ResponseList> 
      <Response> 
       <Description> 
        <Arg /> 
        <Arg /> 
       </Description> 
       <TextualAnalysis version="2.0"> 
        <ExpressionList> 
         <Expression specified=".CLEAN.(Bananas)" total="1" > 
          <Match textView="Attach" truncated="false"> 
           <Surrounding text="..."/> 
           <Surrounding text="Also I don't like... "/> 
           <Matched cleaned="true" text="Bananas " type="expression"/> 
           <Surrounding text="!!!!!!! "/> 
           <Surrounding text="..."/> 
          </Match> 
         </Expression> 
        </ExpressionList> 
       </TextualAnalysis> 
      </Response> 
     </ResponseList> 
    </ChildContext> 
</Context> 
+0

Если XML - это «зверь», предоставьте его сокращенную версию. Трудно помочь без использования XML. – mzjn

+0

csv.writerow() создаст ячейку с линией в ней. Но будет «в начале и в конце этой ячейки». Если вы этого не видите, это может быть потому, что ваш отпечаток c5 не находится на том же уровне, что и ваш writerow. Для отладки я бы напечатал (repr (c5)) на том же уровне отступов, что и писатель ... –

+0

@PatrickMaupin - спасибо, это полезно. Я попробовал команду, которую вы предложили ... запустив print (repr (c5)) в том же отступе, что и writerow, возвращает «Яблоки». Выполнение той же команды в том же отступе, что и c5 = elem.attrib ["text"] возвращает «Яблоки» «Бананы» (на отдельных строках). Запуск команды csv.writerow на том же уровне отступов записывает 2 строки в csv, c1, c2, c3, c4, а c5 имеет другое значение для каждой строки (Яблоки и Бананы). К сожалению, мне нужно сделать то же самое для c4 ... Любые идеи? –

ответ

0

Следующая объединятся все текстовые элементы и поместить их на отдельных строках в одной и той же ячейке внутри вашего CSV. Вы можете изменить разделитель '\ n' на '' или ',', чтобы поместить их в одну строку. Как бы то ни было, у вас могут быть проблемы с некоторыми другими вашими вещами - у вас нет вложенных циклов, и я действительно не понимаю, что вы пытаетесь выполнить, так что, возможно, у вас есть более чем один из этих другие вещи тоже. Во всяком случае:

 c5 = [] 
     for elem in tree.iterfind('ChildContext/ResponseList/Response/TextualAnalysis/ExpressionList/Expression/Match/Matched'): 
       c5.append(elem.attrib["text"]) 
     c.writerow([c1, c2, c3, c4, '\n'.join(c5)]) 
+0

Фантастическая благодарность, которая достигает того, что мне нужно сделать - это действительно был случай получения всех значений c5, и это удалось. –

Смежные вопросы