0

I do have following xml generated by some http response

<?xml version="1.0" encoding="UTF-8"?>
<Response rid="1000" status="succeeded" moreData="false">
  <Results completed="true" total="25" matched="5" processed="25">
      <Resource type="h" DisplayName="Host" name="tango">
          <Time start="2011/12/16/18/46/00" end="2011/12/16/19/46/00"/>
             <PerfData attrId="cpuUsage" attrName="Usage">
                <Data intr="5" start="2011/12/16/19" end="2011/12/16/19" data="36.00"/>
                <Data intr="5" start="2011/12/16/19" end="2011/12/16/19" data="86.00"/>
                <Data intr="5" start="2011/12/16/19" end="2011/12/16/19" data="29.00"/>
             </PerfData>
          <Resource type="vm" DisplayName="VM" name="charlie" baseHost="tango">
              <Time start="2011/12/16/18/46/00" end="2011/12/16/19/46/00"/>
              <PerfData attrId="cpuUsage" attrName="Usage">
                 <Data intr="5" start="2011/12/16/19" end="2011/12/16/19" data="6.00"/>
              </PerfData>
          </Resource>
      </Resource>
  </Result>
</Response>

If you look at this carefully - Outer has one more same tag inside that

So high level xml structure is as below

<Resource>
    <Resource>
    </Resource>
</Resource>

Python ElementTree can parse only outer xml ... Below is my code

pattern = re.compile(r'(<Response.*?</Response>)',
                     re.VERBOSE | re.MULTILINE)

for match in pattern.finditer(data):
    contents = match.group(1)
    responses = xml.fromstring(contents)

    for results in responses:
        result = results.tag

        for resources in results:
            resource = resources.tag
            temp = {}
            temp = resources.attrib
            print temp

This shows following output (temp)

{'typeDisplayName': 'Host', 'type': 'h', 'name': 'tango'}

How can I fetch inner attributes?

1
  • What do you mean by "Outer has one more same tag inside that" Commented Jul 2, 2013 at 13:35

1 Answer 1

2

Don't parse xml with regular expressions! That won't work, use some xml parsing library instead, lxml for instance:

edit: the code example now fetch top resources only, the loop over them and try to fetch "sub resources", this was made after OP request in comment

from lxml import etree

content = '''
YOUR XML HERE
'''

root = etree.fromstring(content)

# search for all "top level" resources
resources = root.xpath("//Resource[not(ancestor::Resource)]")
for resource in resources:
    # copy resource attributes in a dict
    mashup = dict(resource.attrib)
    # find child resource elements
    subresources = resource.xpath("./Resource")
    # if we find only one resource, add it to the mashup
    if len(subresources) == 1:
        mashup['resource'] = dict(subresources[0].attrib)
    # else... not idea what the OP wants...

    print mashup

That will output:

{'resource': {'DisplayName': 'VM', 'type': 'vm', 'name': 'charlie', 'baseHost': 'tango'}, 'DisplayName': 'Host', 'type': 'h', 'name': 'tango'}
Sign up to request clarification or add additional context in comments.

4 Comments

Agreed. etree makes XML parsing much simpler. See the etree documentation for details.
Good catch.. However, it is inadequate.. Just take a look at this xml.. My expected dictionary would be like this - ` { Resource : {'DisplayName' : 'Host' .....}, 'Resource' : {'DisplayName': 'VM', ....} } `
@AbhishekKulkarni that's not a valid python dict, you can't have duplicate keys
@Guillaume My apologize... I am not aware of formatting code in comments here.. However the keys are not duplicate. There are two Keys with the same name "Resource"; one is OUTER KEY and another is INNER key.. so I would rather fetch keys as below - resource_dict = temp['Resource']['Resource'] The above xml parsing generates all "Resource" dictionaries separate. Not as per my expectations. I want Nested dictionary to be generated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.