2017-09-11 20 views
0

xmlファイルの最後のエントリを読み込み、その値を取得します。ここで私は、ファイルの最後のタグで<total><totalpass><totalfail><totalerror>値を取得したいPythonでファイルから最後のエントリを読み取るXML

<TestSuite> 
    <TestCase> 
    <name>tcname1</name> 
    <total>1</total> 
    <totalpass>0</totalpass> 
    <totalfail>0</totalfail> 
    <totalerror>1</totalerror> 
    </TestCase> 
    <TestCase> 
    <name>tcname2</name> 
    <total>1</total> 
    <totalpass>0</totalpass> 
    <totalfail>0</totalfail> 
    <totalerror>1</totalerror> 
    </TestCase> 
</TestSuite> 

私のxmlファイルです。私はこのコードを試してみました。

import xmltodict 
with open(filename) as fd: 
    doc = xmltodict.parse(fd.read()) 
    length=len(doc['TestSuite']['TestCase']) 
    tp=doc['TestSuite']['TestCase'][length-1]['totalpass'] 
    tf=doc['TestSuite']['TestCase'][length-1]['totalfail'] 
    te=doc['TestSuite']['TestCase'][length-1]['totalerror'] 
    total=doc['TestSuite']['TestCase'][length-1]['total'] 

これは、XMLファイル内の2個の以上のテストケースタグとXMLのために働く、しかし、唯一のテストケースタグを持つファイルに対して、このエラーで失敗します。

Traceback (most recent call last): 
    File "HTMLReportGenerationFromXML.py", line 52, in <module> 
    tp=doc['TestSuite']['TestCase'][length-1]['totalpass'] 
KeyError: 4 . 

カウントではなく、サブタグ(長さなどの値)を取っているためです。この問題を解決するのを手伝ってください。

答えて

1

これは私

import xml.etree.ElementTree as ET 
import sys 
tree = ET.parse('temp.xml') 
root = tree.getroot() 
print root 
total=[] 
totalpass=[] 
totalfail=[] 
totalerror=[] 
for test in root.findall('TestCase'): 
    total.append(test.find('total').text) 
    totalpass.append(test.find('totalpass').text) 
    totalfail.append(test.find('totalfail').text) 
    totalerror.append(test.find('totalerror').text) 
length=len(total) 
print total[length-1],totalpass[length-1],totalfail[length-1],totalerror[length-1] 

のために働く、これを試してみました:

import xml.etree.ElementTree as et 

tree = et.parse('test.xml') 

# collect all the test cases 
test_cases = [test_case for test_case in tree.findall('TestCase')] 

# Pull data from the last one 
last = test_cases[-1] 
total = last.find('total').text 
totalpass = last.find('totalpass').text 
totalfail = last.find('totalfail').text 
totalerror = last.find('totalerror').text 

print total,totalpass,totalfail,totalerror 
+0

これはうまく動作します。ありがとうございます。 –

+0

ようこそ。あなたが最も役立つと思われる答えをupvoteおよび/または受け入れてください。 –

1

なぜ私は最初に彼のことをしなかったのですか? xpathを使用します。

最初の例では、xmlファイルを1つのTestCase要素で処理し、2番目のTestCase要素では2つのTestCase要素を処理します。要点は、xpath lastセレクタを使用することです。

>>> from lxml import etree 
>>> tree = etree.parse('temp.xml') 
>>> last_TestCase = tree.xpath('.//TestCase[last()]')[0] 
>>> for child in last_TestCase.iterchildren(): 
...  child.tag, child.text 
... 
('name', 'tcname2') 
('total', '1') 
('totalpass', '0') 
('totalfail', '0') 
('totalerror', '1') 
>>> 
>>> tree = etree.parse('temp_2.xml') 
>>> last_TestCase = tree.xpath('.//TestCase[last()]')[0] 
>>> for child in last_TestCase.iterchildren(): 
...  child.tag, child.text 
... 
('name', 'tcname1') 
('reason', 'reason') 
('total', '2') 
('totalpass', '0') 
('totalfail', '0') 
('totalerror', '2') 
+0

ありがとうございました。しかし、それでもXMLにはこのようなタグが1つしかありません。 tcname1 理由

+0

今私は(私が思う)理解しています。 –

+0

問題は 'doc ['TestSuite'] ['TestCase']'の型にあると思います。それは 'list'か' OrderedDict'のどちらかです。 – floatingpurr

0

あなたのエラーの理由はxmltidictdoc['TestSuite']['TestCase']でちょうど長いXMLS

>>> type(doc2['TestSuite']['TestCase']) # here doc2 is more than one-entry long XML file 
>>> list 

ためのリストであるが、それは1エントリの長いファイル用の辞書のちょうど一種であるということである。

>>> type(doc['TestSuite']['TestCase']) # doc is one-entry long 
>>> collections.OrderedDict 

これが理由です。

また、XML解析に別のライブラリを使用することもできます。

...助けてくれたら教えてください!

+1

ありがとうfloatingpurr。私はこれを試してみましょう。 –

+1

それは私のために完璧に動作します。どうもありがとうございました。 –

+0

良い! :)あなたがそれを好きなら、その答えを受け入れるように自由に感じてください! :) – floatingpurr

0

私はあなたが最後のものだけをしたいので、あなたがそれを取得するために、負のインデックスを使用することができます。この1は私の作品

関連する問題