1

I am now working on a modification so what do I need to do if I want to search for 999 and print the whole blub:Log

I would find 999 by using findLogIter = tree.find("999") but how do I tell him to print the whole thing?

<blub:LogEvents>
 <blub:Log>
  <blub:LogTime>09/03/2017 01:02:16.3216</blub:LogTime>
  <blub:LogIter>999</blub:LogIter>
  <blub:PlugInName>blub:System</blub:PlugInName>
  <blub:EventNumber>100</blub:EventNumber>
  <blub:EventName>I processed something</blub:EventName>
  <blub:EventClass>Process</blub:EventClass>
  <blub:LogMessage><![test message]]></blub:LogMessage>
 </blub:Log>
</blub:LogEvents>

Output should be like this:

09/03/2017 01:02:16.3216,999,blub:System,100,I processed something,Process

1 Answer 1

1

for every Log in LogEvents, find for LogIter and if that subelement has "999" text then call getItemStr() for that Log. If "999" subelement is not present, a None list will be appended. Hence, filter the result list with None.

from xml.etree import ElementTree
tree = ElementTree.parse('sample.xml')
root = tree.getroot()

def getItemStr(item):
    return ','.join([sub_item.text for sub_item in item])

print filter(None,[[getItemStr(item) for child in item.findall('blub:LogIter',{"blub":"Uri"}) if child.text=="999"] for item in root ])

If that last line throws error, You an even use

print filter(None,[[getItemStr(item) for child in item.findall('blub:LogIter') if child.text=="999"] for item in root ])

In python 2.6 and earlier versions, you have to register namespace explicitly like

print filter(None,[[getItemStr(item) for child in item.findall('{Uri}LogIter') if child.text=="999"] for item in root ])

Output:

[['09/03/2017 01:02:16.3216,999,blub:System,100,I processed something,Process,hello']]

Add a namespace like xmlns:blub="Uri" to your xml!

<blub:LogEvents xmlns:blub="Uri">
 <blub:Log>
  <blub:LogTime>09/03/2017 01:02:16.3216</blub:LogTime>
  <blub:LogIter>999</blub:LogIter>
  <blub:PlugInName>blub:System</blub:PlugInName>
  <blub:EventNumber>100</blub:EventNumber>
  <blub:EventName>I processed something</blub:EventName>
  <blub:EventClass>Process</blub:EventClass>
  <blub:LogMessage>hello</blub:LogMessage>
 </blub:Log>
<blub:Log>
  <blub:LogTime>09/03/2011 01:02:16.3216</blub:LogTime>
  <blub:LogIter>1000</blub:LogIter>
  <blub:PlugInName>blub:System</blub:PlugInName>
  <blub:EventNumber>100</blub:EventNumber>
  <blub:EventName>I processed something</blub:EventName>
  <blub:EventClass>Process</blub:EventClass>
  <blub:LogMessage>hi</blub:LogMessage>
 </blub:Log>
</blub:LogEvents>

Hope it helps!

Sign up to request clarification or add additional context in comments.

6 Comments

I get an error: "TypeError: findall() takes exactly 2 arguments (3 given)"
No only two argument is given right! Can you please check again.
And also check if you have added the namespace to xml
Hi, I checked again and copypasted the edited XML from here and it has the same error. test@testserver [python] $ python 1python.py Traceback (most recent call last): File "1python.py", line 8, in <module> print filter(None,[[getItemStr(item) for child in item.findall('blub:LogIter',{"blub":"Uri"}) if child.text=="999"] for item in root ]) TypeError: findall() takes exactly 2 arguments (3 given)
Now I am getting this error: File "1python.py", line 7, in <module> print filter(None,[[getItemStr(item) for child in item.findall('blub:LogIter') if child.text=="999"] for item in root ]) File "/usr/lib/python2.6/xml/etree/ElementTree.py", line 355, in findall return ElementPath.findall(self, path) File "/usr/lib/python2.6/xml/etree/ElementPath.py", line 198, in findall p = Path(path) File "/usr/lib/python2.6/xml/etree/ElementPath.py", line 93, in init "expected path separator (%s)" % (op or tag) SyntaxError: expected path separator (:) I have Python 2.6.4
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.