summaryrefslogtreecommitdiff
path: root/sleekxmpp/xmlstream
diff options
context:
space:
mode:
authorLance Stout <lancestout@gmail.com>2013-01-21 02:34:22 -0800
committerLance Stout <lancestout@gmail.com>2013-01-21 02:34:22 -0800
commitbad405bea96405eb952888dc6996b8b40be85ac4 (patch)
treeb5998707d5d8d836eaa807f1e755047c1aed5c48 /sleekxmpp/xmlstream
parent648f3f978a84445ed188be055453ac4cab3ed4f5 (diff)
parent4f9a95b011277ab64a137aceeb4df2e9fc0f1e25 (diff)
downloadslixmpp-bad405bea96405eb952888dc6996b8b40be85ac4.tar.gz
slixmpp-bad405bea96405eb952888dc6996b8b40be85ac4.tar.bz2
slixmpp-bad405bea96405eb952888dc6996b8b40be85ac4.tar.xz
slixmpp-bad405bea96405eb952888dc6996b8b40be85ac4.zip
Merge branch 'master' into develop
Diffstat (limited to 'sleekxmpp/xmlstream')
-rw-r--r--sleekxmpp/xmlstream/matcher/xmlmask.py67
-rw-r--r--sleekxmpp/xmlstream/matcher/xpath.py37
-rw-r--r--sleekxmpp/xmlstream/stanzabase.py2
3 files changed, 19 insertions, 87 deletions
diff --git a/sleekxmpp/xmlstream/matcher/xmlmask.py b/sleekxmpp/xmlstream/matcher/xmlmask.py
index a0568f08..cb202448 100644
--- a/sleekxmpp/xmlstream/matcher/xmlmask.py
+++ b/sleekxmpp/xmlstream/matcher/xmlmask.py
@@ -14,12 +14,6 @@ from sleekxmpp.xmlstream.stanzabase import ET
from sleekxmpp.xmlstream.matcher.base import MatcherBase
-# Flag indicating if the builtin XPath matcher should be used, which
-# uses namespaces, or a custom matcher that ignores namespaces.
-# Changing this will affect ALL XMLMask matchers.
-IGNORE_NS = False
-
-
log = logging.getLogger(__name__)
@@ -39,10 +33,6 @@ class MatchXMLMask(MatcherBase):
:class:`~sleekxmpp.xmlstream.matcher.stanzapath.StanzaPath`
should be used instead.
- The use of namespaces in the mask comparison is controlled by
- ``IGNORE_NS``. Setting ``IGNORE_NS`` to ``True`` will disable namespace
- based matching for ALL XMLMask matchers.
-
:param criteria: Either an :class:`~xml.etree.ElementTree.Element` XML
object or XML string to use as a mask.
"""
@@ -84,8 +74,6 @@ class MatchXMLMask(MatcherBase):
do not have a specified namespace.
Defaults to ``"__no_ns__"``.
"""
- use_ns = not IGNORE_NS
-
if source is None:
# If the element was not found. May happend during recursive calls.
return False
@@ -96,17 +84,10 @@ class MatchXMLMask(MatcherBase):
mask = ET.fromstring(mask)
except ExpatError:
log.warning("Expat error: %s\nIn parsing: %s", '', mask)
- if not use_ns:
- # Compare the element without using namespaces.
- source_tag = source.tag.split('}', 1)[-1]
- mask_tag = mask.tag.split('}', 1)[-1]
- if source_tag != mask_tag:
- return False
- else:
- # Compare the element using namespaces
- mask_ns_tag = "{%s}%s" % (self.default_ns, mask.tag)
- if source.tag not in [mask.tag, mask_ns_tag]:
- return False
+
+ mask_ns_tag = "{%s}%s" % (self.default_ns, mask.tag)
+ if source.tag not in [mask.tag, mask_ns_tag]:
+ return False
# If the mask includes text, compare it.
if mask.text and source.text and \
@@ -122,37 +103,15 @@ class MatchXMLMask(MatcherBase):
# Recursively check subelements.
matched_elements = {}
for subelement in mask:
- if use_ns:
- matched = False
- for other in source.findall(subelement.tag):
- matched_elements[other] = False
- if self._mask_cmp(other, subelement, use_ns):
- if not matched_elements.get(other, False):
- matched_elements[other] = True
- matched = True
- if not matched:
- return False
- else:
- if not self._mask_cmp(self._get_child(source, subelement.tag),
- subelement, use_ns):
- return False
+ matched = False
+ for other in source.findall(subelement.tag):
+ matched_elements[other] = False
+ if self._mask_cmp(other, subelement, use_ns):
+ if not matched_elements.get(other, False):
+ matched_elements[other] = True
+ matched = True
+ if not matched:
+ return False
# Everything matches.
return True
-
- def _get_child(self, xml, tag):
- """Return a child element given its tag, ignoring namespace values.
-
- Returns ``None`` if the child was not found.
-
- :param xml: The :class:`~xml.etree.ElementTree.Element` XML object
- to search for the given child tag.
- :param tag: The name of the subelement to find.
- """
- tag = tag.split('}')[-1]
- try:
- children = [c.tag.split('}')[-1] for c in xml]
- index = children.index(tag)
- except ValueError:
- return None
- return list(xml)[index]
diff --git a/sleekxmpp/xmlstream/matcher/xpath.py b/sleekxmpp/xmlstream/matcher/xpath.py
index 3f03e68e..f3d28429 100644
--- a/sleekxmpp/xmlstream/matcher/xpath.py
+++ b/sleekxmpp/xmlstream/matcher/xpath.py
@@ -9,16 +9,10 @@
:license: MIT, see LICENSE for more details
"""
-from sleekxmpp.xmlstream.stanzabase import ET
+from sleekxmpp.xmlstream.stanzabase import ET, fix_ns
from sleekxmpp.xmlstream.matcher.base import MatcherBase
-# Flag indicating if the builtin XPath matcher should be used, which
-# uses namespaces, or a custom matcher that ignores namespaces.
-# Changing this will affect ALL XPath matchers.
-IGNORE_NS = False
-
-
class MatchXPath(MatcherBase):
"""
@@ -38,6 +32,9 @@ class MatchXPath(MatcherBase):
expressions will be matched without using namespaces.
"""
+ def __init__(self, criteria):
+ self._criteria = fix_ns(criteria)
+
def match(self, xml):
"""
Compare a stanza's XML contents to an XPath expression.
@@ -59,28 +56,4 @@ class MatchXPath(MatcherBase):
x = ET.Element('x')
x.append(xml)
- if not IGNORE_NS:
- # Use builtin, namespace respecting, XPath matcher.
- if x.find(self._criteria) is not None:
- return True
- return False
- else:
- # Remove namespaces from the XPath expression.
- criteria = []
- for ns_block in self._criteria.split('{'):
- criteria.extend(ns_block.split('}')[-1].split('/'))
-
- # Walk the XPath expression.
- xml = x
- for tag in criteria:
- if not tag:
- # Skip empty tag name artifacts from the cleanup phase.
- continue
-
- children = [c.tag.split('}')[-1] for c in xml]
- try:
- index = children.index(tag)
- except ValueError:
- return False
- xml = list(xml)[index]
- return True
+ return x.find(self._criteria) is not None
diff --git a/sleekxmpp/xmlstream/stanzabase.py b/sleekxmpp/xmlstream/stanzabase.py
index 122d7eb4..120373db 100644
--- a/sleekxmpp/xmlstream/stanzabase.py
+++ b/sleekxmpp/xmlstream/stanzabase.py
@@ -192,7 +192,7 @@ def fix_ns(xpath, split=False, propagate_ns=True, default_ns=''):
for element in elements:
if element:
# Skip empty entry artifacts from splitting.
- if propagate_ns:
+ if propagate_ns and element[0] != '*':
tag = '{%s}%s' % (namespace, element)
else:
tag = element