2017-09-11 5 views
0

Ich möchte den letzten Eintrag der XML-Datei lesen und seinen Wert abrufen. Hier ist meine XML-DateiXML liest den letzten Eintrag aus der Datei in Python

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

ich bekommen die <total>, <totalpass>, <totalfail> und <totalerror> Wert in dem letzten Tag der Datei. Ich habe diesen Code ausprobiert, um das zu tun.

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'] 

Dies funktioniert für die xml mit 2 oder mehr Testcase-Tags in XML-Dateien, aber nicht mit diesem Fehler für die Datei mit nur einem Testfall-Tag.

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

Da anstelle der Zählung, ist es die Untertag (etc Wert als Länge). Bitte helfen Sie mir, dieses Problem zu lösen.

Antwort

1

Da Sie nur die letzte möchten, können Sie negative Indizes verwenden, um es abzurufen:

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

Das funktioniert gut. Danke Mark –

+0

Gern geschehen. Fühlen Sie sich frei, die Antwort, die Sie für am hilfreichsten halten, anzunehmen und/oder zu akzeptieren. –

1

Warum habe ich das nicht gemacht? Verwende XPath.

Das erste Beispiel beinhaltet die Verarbeitung der XML-Datei mit nur einem TestCase-Element, die zweite mit zwei von ihnen. Der Schlüsselpunkt ist, den Xpath last Selektor zu verwenden.

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

Danke Bill. Aber es schlägt immer noch fehl, das XML hat nur ein Tag wie dieses. tcname1 Grund

+0

Jetzt verstehe ich (glaube ich). –

+0

Ich denke, dass das Problem in der Art von 'doc ['TestSuite'] ['TestCase']' liegt. Es könnte entweder eine 'liste' oder eine' OrderedDict' sein. – floatingpurr

0

Der Grund Ihres Fehler ist, dass mit xmltidictdoc['TestSuite']['TestCase'] ist eine Liste nur für lange XMLs

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

aber es ist nur eine Art Wörterbuch für eine lange Datei eines Eintrags:

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

Das ist der Grund. Sie könnten versuchen, das Problem in der folgenden Art und Weise zu verwalten:

import xmltodict 
with open(filename) as fd: 
    doc = xmltodict.parse(fd.read()) 

    if type(doc['TestSuite']['TestCase']) == list:  
     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'] 

    else: # you have just a dict here 
     tp=doc['TestSuite']['TestCase']['totalpass'] 

     tf=doc['TestSuite']['TestCase']['totalfail'] 

     te=doc['TestSuite']['TestCase']['totalerror'] 

     total=doc['TestSuite']['TestCase']['total'] 

Andernfalls können Sie eine andere Bibliothek für das Parsen von XML verwenden.

... lass es mich wissen, wenn es hilft!

+1

danke schwebender purr. Lass mich das versuchen. –

+1

Es funktioniert perfekt für mich. Vielen Dank für mich. –

+0

Gut! :) Fühlen Sie sich frei, diese Antwort zu akzeptieren, wenn es Ihnen gefallen hat! :) – floatingpurr

0

Ich habe versucht, dies für mich arbeitet

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] 

Dieses ist für mich arbeitet

Verwandte Themen