Allow for simplified XPath namespaces
This commit is contained in:
parent
d86adfa1b1
commit
ccf7916257
2 changed files with 6 additions and 33 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue