Allow for simplified XPath namespaces
This commit is contained in:
parent
d86adfa1b1
commit
ccf7916257
@ -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
|
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user