summaryrefslogtreecommitdiff
path: root/sleekxmpp/xmlstream/stanzabase.py
diff options
context:
space:
mode:
Diffstat (limited to 'sleekxmpp/xmlstream/stanzabase.py')
-rw-r--r--sleekxmpp/xmlstream/stanzabase.py88
1 files changed, 47 insertions, 41 deletions
diff --git a/sleekxmpp/xmlstream/stanzabase.py b/sleekxmpp/xmlstream/stanzabase.py
index d1409706..dff8c997 100644
--- a/sleekxmpp/xmlstream/stanzabase.py
+++ b/sleekxmpp/xmlstream/stanzabase.py
@@ -77,6 +77,49 @@ def register_stanza_plugin(stanza, plugin, iterable=False, overrides=False):
registerStanzaPlugin = register_stanza_plugin
+def fix_ns(xpath, split=False, propagate_ns=True, default_ns=''):
+ """Apply the stanza's namespace to elements in an XPath expression.
+
+ :param string xpath: The XPath expression to fix with namespaces.
+ :param bool split: Indicates if the fixed XPath should be left as a
+ list of element names with namespaces. Defaults to
+ False, which returns a flat string path.
+ :param bool propagate_ns: Overrides propagating parent element
+ namespaces to child elements. Useful if
+ you wish to simply split an XPath that has
+ non-specified namespaces, and child and
+ parent namespaces are known not to always
+ match. Defaults to True.
+ """
+ fixed = []
+ # Split the XPath into a series of blocks, where a block
+ # is started by an element with a namespace.
+ ns_blocks = xpath.split('{')
+ for ns_block in ns_blocks:
+ if '}' in ns_block:
+ # Apply the found namespace to following elements
+ # that do not have namespaces.
+ namespace = ns_block.split('}')[0]
+ elements = ns_block.split('}')[1].split('/')
+ else:
+ # Apply the stanza's namespace to the following
+ # elements since no namespace was provided.
+ namespace = default_ns
+ elements = ns_block.split('/')
+
+ for element in elements:
+ if element:
+ # Skip empty entry artifacts from splitting.
+ if propagate_ns:
+ tag = '{%s}%s' % (namespace, element)
+ else:
+ tag = element
+ fixed.append(tag)
+ if split:
+ return fixed
+ return '/'.join(fixed)
+
+
class ElementBase(object):
"""
@@ -760,7 +803,7 @@ class ElementBase(object):
may be either a string or a list of element
names with attribute checks.
"""
- if isinstance(xpath, str):
+ if not isinstance(xpath, list):
xpath = self._fix_ns(xpath, split=True, propagate_ns=False)
# Extract the tag name and attribute checks for the first XPath node.
@@ -952,46 +995,9 @@ class ElementBase(object):
return self
def _fix_ns(self, xpath, split=False, propagate_ns=True):
- """Apply the stanza's namespace to elements in an XPath expression.
-
- :param string xpath: The XPath expression to fix with namespaces.
- :param bool split: Indicates if the fixed XPath should be left as a
- list of element names with namespaces. Defaults to
- False, which returns a flat string path.
- :param bool propagate_ns: Overrides propagating parent element
- namespaces to child elements. Useful if
- you wish to simply split an XPath that has
- non-specified namespaces, and child and
- parent namespaces are known not to always
- match. Defaults to True.
- """
- fixed = []
- # Split the XPath into a series of blocks, where a block
- # is started by an element with a namespace.
- ns_blocks = xpath.split('{')
- for ns_block in ns_blocks:
- if '}' in ns_block:
- # Apply the found namespace to following elements
- # that do not have namespaces.
- namespace = ns_block.split('}')[0]
- elements = ns_block.split('}')[1].split('/')
- else:
- # Apply the stanza's namespace to the following
- # elements since no namespace was provided.
- namespace = self.namespace
- elements = ns_block.split('/')
-
- for element in elements:
- if element:
- # Skip empty entry artifacts from splitting.
- if propagate_ns:
- tag = '{%s}%s' % (namespace, element)
- else:
- tag = element
- fixed.append(tag)
- if split:
- return fixed
- return '/'.join(fixed)
+ return fix_ns(xpath, split=split,
+ propagate_ns=propagate_ns,
+ default_ns=self.namespace)
def __eq__(self, other):
"""Compare the stanza object with another to test for equality.