I need to check whether a certain tag exists in an xml file.
For example, I want to see if the tag exists in this snippet:
<main>
<elem1/>
<elem2>Hi</elem2>
<elem3/>
...
</main>
Currently, I am using an ugly hack with error checking, like this:
try:
if root.elem1.tag:
foo = elem1
except AttributeEr开发者_Python百科ror:
foo = "error finding elem1"
I also want to customize the string if it is unable to find the node (i.e. "unable to find -tagname-").
I have to check a long list of variables, and I don't want to repeat the code 100 times.
Any suggestions?
Edit:
Here is a snip of the actual xml file:
<main>
<asset name="Virtual Dvaered Unpresence">
<virtual/>
<presence>
<faction>Dvaered</faction>
<value>-1000.000000</value>
<range>0</range>
</presence>
</asset>
<asset name="Virtual Empire Small">
<virtual/>
<presence>
<faction>Empire</faction>
<value>100.000000</value>
<range>2</range>
</presence>
</asset>
</main>
I want to check whether the tag exists, and, if so, to get the contents.
Edit edit: Ok, I am going to combine two of the answers, but I can only vote for one. Sorry.
Edit 3: Related question about XPath here: Python lxml (objectify): Xpath troubles
hasattr()
works for this:
if hasattr(root, 'elem1'):
foo = root.elem1
Edit: updated answer for sample file.
I'm assuming you want to search each asset for certain tags. If so, the following worked for me:
import lxml.objectify
# Parse the file.
tree = lxml.objectify.parse('sample.xml')
root = tree.getroot()
# Which elements to find.
to_find = set(['presence/faction', 'presence/value', 'fake'])
# Go through each asset in the document.
for asset in root.findall('asset'):
# Check for each element.
for name in to_find:
node = asset.find(name)
if node is not None:
print 'Found %s, its value is %s' % (name, node)
else:
print 'Unable to find %s' % name
The output was:
Found presence/value, its value is -1000.0
Found presence/faction, its value is Dvaered
Unable to find fake
Found presence/value, its value is 100.0
Found presence/faction, its value is Empire
Unable to find fake
Assume you want to get elem2's value, you can use xpath to find it.
tree = etree.parse(StringIO(htmlString), etree.HTMLParser()).getroot()
youWantValue = tree.xpath('/main/elem2')[0].text
If your document tends to be relatively short you can iterate over all children of <main>
looking for tags matching your set of variable names:
tree = lxml.etree.fromstring(DATA)
NAMES = set(['elem1', 'elem3'])
for node in tree.iterchildren():
if node.tag in NAMES:
print 'found', node.tag
Or you can search for each variable name one at a time:
for tag in ('elem1', 'elem3'):
if tree.find(tag) is not None:
print 'found', tag
精彩评论