3

I have the following XML format, and I want to pull out the values for name, region, and status using python's xml.etree.ElementTree module.

However, my attempt to get this information has been unsuccessful so far.

<feed>
    <entry>
        <id>uuid:asdfadsfasdf123123</id>
        <title type="text"></title>
        <content type="application/xml">
            <NamespaceDescription xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                <Name>instancename</Name>
                <Region>US</Region>
                <Status>Active</Status>
            </NamespaceDescription>
        </content>
    </entry>
    <entry>
        <id>uuid:asdfadsfasdf234234</id>
        <title type="text"></title>
        <content type="application/xml">
            <NamespaceDescription xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                <Name>instancename2</Name>
                <Region>US2</Region>
                <Status>Active</Status>
            </NamespaceDescription>
        </content>
    </entry>
</feed>

My code attempt:

NAMESPACE = '{http://www.w3.org/2005/Atom}'
root = et.fromstring(XML_STRING)
entry_root = root.findall('{0}entry'.format(NAMESPACE))
for child in entry_root:
    content_node = child.find('{0}content'.format(NAMESPACE))
    for content in content_node:
        for desc in content.iter():
            print desc.tag
            name = desc.find('{0}Name'.format(NAMESPACE))
            print name

desc.tag is giving me the nodes I want to access, but name is returning None. Any ideas what's wrong with my code?

Output of desc.tag:

{http://schemas.microsoft.com/netservices/2010/10/servicebus/connect}Name
{http://schemas.microsoft.com/netservices/2010/10/servicebus/connect}Region
{http://schemas.microsoft.com/netservices/2010/10/servicebus/connect}Status

2 Answers 2

2

I don't know why I didn't see this before. But, I was able to get the values.

root = et.fromstring(XML_STRING)
entry_root = root.findall('{0}entry'.format(NAMESPACE))
for child in entry_root:
    content_node = child.find('{0}content'.format(NAMESPACE))
    for descr in content_node:
        name_node = descr.find('{0}Name'.format(NAMESPACE))
        print name_node.text
Sign up to request clarification or add additional context in comments.

1 Comment

How do you do this if the xml files are already on your pc, instead of having to download them?
1

You can use lxml.etree along with default namespace mapping to parse the XML as follows:

content = '''
<feed>
    <entry>
        <id>uuid:asdfadsfasdf123123</id>
        <title type="text"></title>
        <content type="application/xml">
            <NamespaceDescription xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                <Name>instancename</Name>
                <Region>US</Region>
                <Status>Active</Status>
            </NamespaceDescription>
        </content>
    </entry>
    <entry>
        <id>uuid:asdfadsfasdf234234</id>
        <title type="text"></title>
        <content type="application/xml">
            <NamespaceDescription xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                <Name>instancename2</Name>
                <Region>US2</Region>
                <Status>Active</Status>
            </NamespaceDescription>
        </content>
    </entry>
</feed>'''

from lxml import etree

tree = etree.XML(content)
ns = {'default': 'http://schemas.microsoft.com/netservices/2010/10/servicebus/connect'}

names = tree.xpath('//default:Name/text()', namespaces=ns)
regions = tree.xpath('//default:Region/text()', namespaces=ns)
statuses = tree.xpath('//default:Status/text()', namespaces=ns)

print(names)
print(regions)
print(statuses)

Output

['instancename', 'instancename2']
['US', 'US2']
['Active', 'Active']

This XPath/namespace functionality can be adapted to output the data in any format you require.

2 Comments

Thanks for the response. I should've mentioned I'm limited to 'xml.etree.ElementTree'
OK - I will see what I can do. In the meantime, see if you can install lxml - it is IMO the best XML parsing module for Python. Run pip install lxml from your command line to install.

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.