iNoob
iNoob

Reputation: 1395

XML parsing specific values - Python

I've been attempting to parse a list of xml files. I'd like to print specific values such as the userName value.

<?xml version="1.0" encoding="utf-8"?>
<Drives clsid="{8FDDCC1A-0C3C-43cd-A6B4-71A6DF20DA8C}" 
        disabled="1">
  <Drive clsid="{935D1B74-9CB8-4e3c-9914-7DD559B7A417}" 
         name="S:" 
         status="S:" 
         image="2" 
         changed="2007-07-06 20:57:37" 
         uid="{4DA4A7E3-F1D8-4FB1-874F-D2F7D16F7065}">
    <Properties action="U" 
                thisDrive="NOCHANGE" 
                allDrives="NOCHANGE" 
                userName="" 
                cpassword="" 
                path="\\scratch" 
                label="SCRATCH" 
                persistent="1" 
                useLetter="1" 
                letter="S"/>
  </Drive>
</Drives>

My script is working fine collecting a list of xml files etc. However the below function is to print the relevant values. I'm trying to achieve this as suggested in this post. However I'm clearly doing something incorrectly as I'm getting errors suggesting that elm object has no attribute text. Any help would be appreciated.

Current Code

from lxml import etree as ET

def read_files(files):
    for fi in files:
        doc = ET.parse(fi)
        elm = doc.find('userName')
        print elm.text

Upvotes: 0

Views: 272

Answers (3)

ROMANIA_engineer
ROMANIA_engineer

Reputation: 56616

You can try to take the element using the tag name and then try to take its attribute (userName is an attribute for Properties):

from lxml import etree as ET

def read_files(files):
    for fi in files:
        doc = ET.parse(fi)
        props = doc.getElementsByTagName('Properties') 
        elm = props[0].attributes['userName']
        print elm.value

Upvotes: 0

Dan Lenski
Dan Lenski

Reputation: 79732

doc.find looks for a tag with the given name. You are looking for an attribute with the given name.

elm.text is giving you an error because doc.find doesn't find any tags, so it returns None, which has no text property.

Read the lxml.etree docs some more, and then try something like this:

doc = ET.parse(fi)
root = doc.getroot()
prop = root.find(".//Properties") # finds the first <Properties> tag anywhere
elm = prop.attrib['userName']

Upvotes: 1

Charles Duffy
Charles Duffy

Reputation: 295272

userName is an attribute, not an element. Attributes don't have text nodes attached to them at all.

for el in doc.xpath('//*[@userName]'):
  print el.attrib['userName']

Upvotes: 1

Related Questions