Fix data_value() in XPathToken
This commit is contained in:
parent
72a99dc39f
commit
4aeee2bb34
|
@ -2,8 +2,10 @@
|
|||
CHANGELOG
|
||||
*********
|
||||
|
||||
`v1.2.2`_ (TBD)
|
||||
`v1.3.0`_ (TBD)
|
||||
===============
|
||||
* Improve typed selection with TypedAttribute and TypedElement named tuples
|
||||
* Add iter_results to XPathContext
|
||||
* Fix descendant shortcut operator '//'
|
||||
* Fix text() function
|
||||
* Fix typed select of '(name)' token
|
||||
|
|
|
@ -257,6 +257,10 @@ def select(self, context=None):
|
|||
for item in context.iter_children_or_self():
|
||||
xsd_type = self.match_xsd_type(item, name)
|
||||
if xsd_type is not None:
|
||||
if self.is_root:
|
||||
yield item
|
||||
continue
|
||||
|
||||
primitive_type = self.parser.schema.get_primitive_type(xsd_type)
|
||||
value = XSD_BUILTIN_TYPES[primitive_type.local_name].value
|
||||
if isinstance(item, AttributeNode):
|
||||
|
@ -276,10 +280,18 @@ def select(self, context=None):
|
|||
for item in context.iter_children_or_self():
|
||||
try:
|
||||
if is_attribute_node(item, name):
|
||||
yield TypedAttribute(item, self.xsd_type.decode(item[1]))
|
||||
if self.is_root:
|
||||
yield self.xsd_type.decode(item[1])
|
||||
else:
|
||||
yield TypedAttribute(item, self.xsd_type.decode(item[1]))
|
||||
elif is_element_node(item, tag):
|
||||
if self.xsd_type.is_simple() or self.xsd_type.has_simple_content():
|
||||
yield TypedElement(item, self.xsd_type.decode(item.text))
|
||||
if isinstance(item, TypedElement):
|
||||
yield item[1] if self.is_root else item
|
||||
elif self.xsd_type.is_simple() or self.xsd_type.has_simple_content():
|
||||
if self.is_root:
|
||||
yield self.xsd_type.decode(item.text)
|
||||
else:
|
||||
yield TypedElement(item, self.xsd_type.decode(item.text))
|
||||
else:
|
||||
yield item
|
||||
except (TypeError, ValueError):
|
||||
|
@ -672,20 +684,32 @@ def select(self, context=None):
|
|||
elif len(self) == 1:
|
||||
context.item = None
|
||||
for result in self[0].select(context):
|
||||
yield result
|
||||
if isinstance(result, (AttributeNode, TypedAttribute, TypedElement)):
|
||||
yield result[1] if self.is_root else result
|
||||
else:
|
||||
yield result
|
||||
else:
|
||||
items = set()
|
||||
items = []
|
||||
context2 = context.copy()
|
||||
left_results = list(self[0].select(context))
|
||||
context.size = len(left_results)
|
||||
for context.position, context.item in enumerate(left_results):
|
||||
if not is_xpath_node(context.item):
|
||||
self.wrong_type("left operand must returns XPath nodes: {}".format(context.item))
|
||||
for result in self[1].select(context):
|
||||
if is_etree_element(result) or isinstance(result, tuple):
|
||||
if result not in items:
|
||||
yield result
|
||||
items.add(result)
|
||||
if not is_etree_element(result) and not isinstance(result, tuple):
|
||||
yield result
|
||||
elif result in items:
|
||||
pass
|
||||
elif isinstance(result, (TypedAttribute, TypedElement)):
|
||||
if result[0] not in items:
|
||||
items.append(result)
|
||||
yield result[1] if self.is_root else result
|
||||
elif isinstance(result, AttributeNode):
|
||||
items.append(result)
|
||||
yield result[1] if self.is_root else result
|
||||
else:
|
||||
items.append(result)
|
||||
yield result
|
||||
|
||||
|
||||
|
@ -808,16 +832,21 @@ def select(self, context=None):
|
|||
@method(axis('following-sibling'))
|
||||
def select(self, context=None):
|
||||
if context is not None:
|
||||
if is_element_node(context.item):
|
||||
if isinstance(context.item, TypedElement):
|
||||
item = context.item[0]
|
||||
elif is_etree_element(context.item):
|
||||
item = context.item
|
||||
for elem in context.iter_parent(axis=self.symbol):
|
||||
follows = False
|
||||
for child in context.iter_children_or_self(elem, child_axis=True):
|
||||
if follows:
|
||||
for result in self[0].select(context):
|
||||
yield result
|
||||
elif item is child:
|
||||
follows = True
|
||||
else:
|
||||
return
|
||||
|
||||
for elem in context.iter_parent(axis=self.symbol):
|
||||
follows = False
|
||||
for child in context.iter_children_or_self(elem, child_axis=True):
|
||||
if follows:
|
||||
for result in self[0].select(context):
|
||||
yield result
|
||||
elif item is child:
|
||||
follows = True
|
||||
|
||||
|
||||
@method(axis('following'))
|
||||
|
|
|
@ -468,7 +468,8 @@ def evaluate(self, context=None):
|
|||
for results in product(*selectors):
|
||||
for i in range(len(results)):
|
||||
context.variables[self[i * 2][0].value] = results[i]
|
||||
if self.boolean_value(list(self[-1].select(context.copy()))):
|
||||
|
||||
if self.boolean_value([x for x in self[-1].select(context.copy())]):
|
||||
if some:
|
||||
return True
|
||||
elif not some:
|
||||
|
|
|
@ -27,7 +27,7 @@ from decimal import Decimal
|
|||
from .compat import string_base_type, unicode_type
|
||||
from .exceptions import xpath_error
|
||||
from .namespaces import XQT_ERRORS_NAMESPACE
|
||||
from .xpath_nodes import AttributeNode, is_etree_element, is_attribute_node, \
|
||||
from .xpath_nodes import AttributeNode, TypedElement, is_etree_element, is_attribute_node, \
|
||||
elem_iter_strings, is_text_node, is_namespace_node, is_comment_node, \
|
||||
is_processing_instruction_node, is_element_node, is_document_node, \
|
||||
is_xpath_node, is_schema_node
|
||||
|
@ -430,7 +430,7 @@ class XPathToken(Token):
|
|||
The typed value, as computed by fn:data() on each item. Returns an instance of
|
||||
UntypedAtomic.
|
||||
"""
|
||||
if is_attribute_node(obj):
|
||||
if is_attribute_node(obj) or isinstance(obj, TypedElement):
|
||||
obj = obj[1]
|
||||
|
||||
if obj is None:
|
||||
|
|
Loading…
Reference in New Issue