Allow for simplified XPath namespaces

This commit is contained in:
Lance Stout 2013-01-20 15:43:02 -08:00
parent d86adfa1b1
commit ccf7916257
2 changed files with 6 additions and 33 deletions

View File

@ -9,16 +9,10 @@
:license: MIT, see LICENSE for more details :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 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): class MatchXPath(MatcherBase):
""" """
@ -38,6 +32,9 @@ class MatchXPath(MatcherBase):
expressions will be matched without using namespaces. expressions will be matched without using namespaces.
""" """
def __init__(self, criteria):
self._criteria = fix_ns(criteria)
def match(self, xml): def match(self, xml):
""" """
Compare a stanza's XML contents to an XPath expression. Compare a stanza's XML contents to an XPath expression.
@ -59,28 +56,4 @@ class MatchXPath(MatcherBase):
x = ET.Element('x') x = ET.Element('x')
x.append(xml) x.append(xml)
if not IGNORE_NS: return x.find(self._criteria) is not None
# 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

View File

@ -192,7 +192,7 @@ def fix_ns(xpath, split=False, propagate_ns=True, default_ns=''):
for element in elements: for element in elements:
if element: if element:
# Skip empty entry artifacts from splitting. # Skip empty entry artifacts from splitting.
if propagate_ns: if propagate_ns and element[0] != '*':
tag = '{%s}%s' % (namespace, element) tag = '{%s}%s' % (namespace, element)
else: else:
tag = element tag = element