diff options
author | Vishvananda Ishaya <vishvananda@gmail.com> | 2011-02-23 15:32:31 -0800 |
---|---|---|
committer | Vishvananda Ishaya <vishvananda@gmail.com> | 2011-02-23 15:32:31 -0800 |
commit | 80970a82f1d23611291144ed41362d4c535c70e0 (patch) | |
tree | 8e9bdc4d22612162ae1bee47bccd5d61faddef37 /nova/utils.py | |
parent | 19dc13131b7fe512cb7897a888093b5c9a62e69d (diff) | |
parent | 5e2f82b1487b8f8e43539d0c71466fbbfed23121 (diff) | |
download | nova-80970a82f1d23611291144ed41362d4c535c70e0.tar.gz nova-80970a82f1d23611291144ed41362d4c535c70e0.tar.xz nova-80970a82f1d23611291144ed41362d4c535c70e0.zip |
merged upstream
Diffstat (limited to 'nova/utils.py')
-rw-r--r-- | nova/utils.py | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/nova/utils.py b/nova/utils.py index 2a3acf042..0cf91e0cc 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -2,6 +2,7 @@ # Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. +# Copyright 2011 Justin Santa Barbara # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -31,6 +32,7 @@ import string import struct import sys import time +import types from xml.sax import saxutils import re import netaddr @@ -499,3 +501,52 @@ def ensure_b64_encoding(val): return val except TypeError: return base64.b64encode(val) + + +def get_from_path(items, path): + """ Returns a list of items matching the specified path. Takes an + XPath-like expression e.g. prop1/prop2/prop3, and for each item in items, + looks up items[prop1][prop2][prop3]. Like XPath, if any of the + intermediate results are lists it will treat each list item individually. + A 'None' in items or any child expressions will be ignored, this function + will not throw because of None (anywhere) in items. The returned list + will contain no None values.""" + + if path is None: + raise exception.Error("Invalid mini_xpath") + + (first_token, sep, remainder) = path.partition("/") + + if first_token == "": + raise exception.Error("Invalid mini_xpath") + + results = [] + + if items is None: + return results + + if not isinstance(items, types.ListType): + # Wrap single objects in a list + items = [items] + + for item in items: + if item is None: + continue + get_method = getattr(item, "get", None) + if get_method is None: + continue + child = get_method(first_token) + if child is None: + continue + if isinstance(child, types.ListType): + # Flatten intermediate lists + for x in child: + results.append(x) + else: + results.append(child) + + if not sep: + # No more tokens + return results + else: + return get_from_path(results, remainder) |