elementpath 5.0.2__tar.gz → 5.0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. {elementpath-5.0.2 → elementpath-5.0.3}/CHANGELOG.rst +5 -0
  2. {elementpath-5.0.2/elementpath.egg-info → elementpath-5.0.3}/PKG-INFO +1 -1
  3. {elementpath-5.0.2 → elementpath-5.0.3}/doc/conf.py +1 -1
  4. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/__init__.py +1 -1
  5. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/tree_builders.py +5 -4
  6. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath_nodes.py +17 -3
  7. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath_tokens.py +16 -8
  8. {elementpath-5.0.2 → elementpath-5.0.3/elementpath.egg-info}/PKG-INFO +1 -1
  9. {elementpath-5.0.2 → elementpath-5.0.3}/pyproject.toml +1 -1
  10. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_xpath1_parser.py +39 -0
  11. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_xpath_tokens.py +3 -1
  12. {elementpath-5.0.2 → elementpath-5.0.3}/tox.ini +2 -2
  13. {elementpath-5.0.2 → elementpath-5.0.3}/LICENSE +0 -0
  14. {elementpath-5.0.2 → elementpath-5.0.3}/MANIFEST.in +0 -0
  15. {elementpath-5.0.2 → elementpath-5.0.3}/README.rst +0 -0
  16. {elementpath-5.0.2 → elementpath-5.0.3}/doc/Makefile +0 -0
  17. {elementpath-5.0.2 → elementpath-5.0.3}/doc/advanced.rst +0 -0
  18. {elementpath-5.0.2 → elementpath-5.0.3}/doc/index.rst +0 -0
  19. {elementpath-5.0.2 → elementpath-5.0.3}/doc/introduction.rst +0 -0
  20. {elementpath-5.0.2 → elementpath-5.0.3}/doc/make.bat +0 -0
  21. {elementpath-5.0.2 → elementpath-5.0.3}/doc/pratt_api.rst +0 -0
  22. {elementpath-5.0.2 → elementpath-5.0.3}/doc/requirements.txt +0 -0
  23. {elementpath-5.0.2 → elementpath-5.0.3}/doc/xpath_api.rst +0 -0
  24. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/aliases.py +0 -0
  25. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/collations.py +0 -0
  26. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/compare.py +0 -0
  27. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/datatypes/__init__.py +0 -0
  28. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/datatypes/atomic_types.py +0 -0
  29. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/datatypes/binary.py +0 -0
  30. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/datatypes/datetime.py +0 -0
  31. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/datatypes/numeric.py +0 -0
  32. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/datatypes/proxies.py +0 -0
  33. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/datatypes/qname.py +0 -0
  34. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/datatypes/string.py +0 -0
  35. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/datatypes/untyped.py +0 -0
  36. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/datatypes/uri.py +0 -0
  37. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/decoder.py +0 -0
  38. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/etree.py +0 -0
  39. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/exceptions.py +0 -0
  40. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/extras/__init__.py +0 -0
  41. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/extras/pathnodes.py +0 -0
  42. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/helpers.py +0 -0
  43. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/namespaces.py +0 -0
  44. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/protocols.py +0 -0
  45. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/py.typed +0 -0
  46. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/regex/__init__.py +0 -0
  47. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/regex/categories_fallback.py +0 -0
  48. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/regex/character_classes.py +0 -0
  49. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/regex/codepoints.py +0 -0
  50. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/regex/patterns.py +0 -0
  51. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/regex/unicode_blocks.py +0 -0
  52. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/regex/unicode_categories.py +0 -0
  53. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/regex/unicode_subsets.py +0 -0
  54. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/schema_proxy.py +0 -0
  55. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/sequence_types.py +0 -0
  56. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/serialization.py +0 -0
  57. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/tdop.py +0 -0
  58. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/validators/__init__.py +0 -0
  59. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/validators/analyze-string.xsd +0 -0
  60. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/validators/schema-for-json.xsd +0 -0
  61. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath1/__init__.py +0 -0
  62. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath1/_xpath1_axes.py +0 -0
  63. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath1/_xpath1_functions.py +0 -0
  64. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath1/_xpath1_operators.py +0 -0
  65. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath1/xpath1_parser.py +0 -0
  66. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath2/__init__.py +0 -0
  67. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath2/_xpath2_constructors.py +0 -0
  68. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath2/_xpath2_functions.py +0 -0
  69. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath2/_xpath2_operators.py +0 -0
  70. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath2/xpath2_parser.py +0 -0
  71. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath3.py +0 -0
  72. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath30/__init__.py +0 -0
  73. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath30/_translation_maps.py +0 -0
  74. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath30/_xpath30_functions.py +0 -0
  75. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath30/_xpath30_operators.py +0 -0
  76. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath30/xpath30_helpers.py +0 -0
  77. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath30/xpath30_parser.py +0 -0
  78. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath31/__init__.py +0 -0
  79. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath31/_xpath31_functions.py +0 -0
  80. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath31/_xpath31_operators.py +0 -0
  81. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath31/xpath31_parser.py +0 -0
  82. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath_context.py +0 -0
  83. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath/xpath_selectors.py +0 -0
  84. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath.egg-info/SOURCES.txt +0 -0
  85. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath.egg-info/dependency_links.txt +0 -0
  86. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath.egg-info/requires.txt +0 -0
  87. {elementpath-5.0.2 → elementpath-5.0.3}/elementpath.egg-info/top_level.txt +0 -0
  88. {elementpath-5.0.2 → elementpath-5.0.3}/requirements-dev.txt +0 -0
  89. {elementpath-5.0.2 → elementpath-5.0.3}/scripts/generate_codepoints.py +0 -0
  90. {elementpath-5.0.2 → elementpath-5.0.3}/setup.cfg +0 -0
  91. {elementpath-5.0.2 → elementpath-5.0.3}/tests/__init__.py +0 -0
  92. {elementpath-5.0.2 → elementpath-5.0.3}/tests/memory_profiling.py +0 -0
  93. {elementpath-5.0.2 → elementpath-5.0.3}/tests/mypy_tests/advanced.py +0 -0
  94. {elementpath-5.0.2 → elementpath-5.0.3}/tests/mypy_tests/protocols.py +0 -0
  95. {elementpath-5.0.2 → elementpath-5.0.3}/tests/mypy_tests/selectors.py +0 -0
  96. {elementpath-5.0.2 → elementpath-5.0.3}/tests/resources/analyze-string.xsd +0 -0
  97. {elementpath-5.0.2 → elementpath-5.0.3}/tests/resources/external_entity.xml +0 -0
  98. {elementpath-5.0.2 → elementpath-5.0.3}/tests/resources/sample.xml +0 -0
  99. {elementpath-5.0.2 → elementpath-5.0.3}/tests/resources/schema-for-json.xsd +0 -0
  100. {elementpath-5.0.2 → elementpath-5.0.3}/tests/resources/unparsed_entity.xml +0 -0
  101. {elementpath-5.0.2 → elementpath-5.0.3}/tests/resources/unused_external_entity.xml +0 -0
  102. {elementpath-5.0.2 → elementpath-5.0.3}/tests/resources/unused_unparsed_entity.xml +0 -0
  103. {elementpath-5.0.2 → elementpath-5.0.3}/tests/resources/with_entity.xml +0 -0
  104. {elementpath-5.0.2 → elementpath-5.0.3}/tests/run_all_tests.py +0 -0
  105. {elementpath-5.0.2 → elementpath-5.0.3}/tests/run_typing_tests.py +0 -0
  106. {elementpath-5.0.2 → elementpath-5.0.3}/tests/run_w3c_tests.py +0 -0
  107. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_collations.py +0 -0
  108. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_compare.py +0 -0
  109. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_datatypes.py +0 -0
  110. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_decoder.py +0 -0
  111. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_etree.py +0 -0
  112. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_exceptions.py +0 -0
  113. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_helpers.py +0 -0
  114. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_namespaces.py +0 -0
  115. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_package.py +0 -0
  116. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_pathnodes.py +0 -0
  117. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_regex.py +0 -0
  118. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_schema_context.py +0 -0
  119. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_schema_proxy.py +0 -0
  120. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_selectors.py +0 -0
  121. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_sequence_types.py +0 -0
  122. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_serialization.py +0 -0
  123. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_tdop_parser.py +0 -0
  124. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_tree_builders.py +0 -0
  125. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_validators.py +0 -0
  126. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_xpath2_constructors.py +0 -0
  127. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_xpath2_functions.py +0 -0
  128. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_xpath2_parser.py +0 -0
  129. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_xpath30.py +0 -0
  130. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_xpath31.py +0 -0
  131. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_xpath_context.py +0 -0
  132. {elementpath-5.0.2 → elementpath-5.0.3}/tests/test_xpath_nodes.py +0 -0
  133. {elementpath-5.0.2 → elementpath-5.0.3}/tests/xpath_test_class.py +0 -0
@@ -2,6 +2,10 @@
2
2
  CHANGELOG
3
3
  *********
4
4
 
5
+ `v5.0.3`_ (2025-06-28)
6
+ ======================
7
+ * Fix for XPath 1.0 processing of schema annotated XML data (issue #93)
8
+
5
9
  `v5.0.2`_ (2025-06-18)
6
10
  ======================
7
11
  * Fix for XPath 2.0 *fn:node-name* (issue #91)
@@ -513,3 +517,4 @@ CHANGELOG
513
517
  .. _v5.0.0: https://github.com/sissaschool/elementpath/compare/v4.8.0...v5.0.0
514
518
  .. _v5.0.1: https://github.com/sissaschool/elementpath/compare/v5.0.0...v5.0.1
515
519
  .. _v5.0.2: https://github.com/sissaschool/elementpath/compare/v5.0.1...v5.0.2
520
+ .. _v5.0.3: https://github.com/sissaschool/elementpath/compare/v5.0.2...v5.0.3
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: elementpath
3
- Version: 5.0.2
3
+ Version: 5.0.3
4
4
  Summary: XPath 1.0/2.0/3.0/3.1 parsers and selectors for ElementTree and lxml
5
5
  Author-email: Davide Brunato <brunato@sissa.it>
6
6
  License-Expression: MIT
@@ -31,7 +31,7 @@ author = 'Davide Brunato'
31
31
  # The short X.Y version
32
32
  version = '5.0'
33
33
  # The full version, including alpha/beta/rc tags
34
- release = '5.0.2'
34
+ release = '5.0.3'
35
35
 
36
36
  # -- General configuration ---------------------------------------------------
37
37
 
@@ -7,7 +7,7 @@
7
7
  #
8
8
  # @author Davide Brunato <brunato@sissa.it>
9
9
  #
10
- __version__ = '5.0.2'
10
+ __version__ = '5.0.3'
11
11
  __author__ = "Davide Brunato"
12
12
  __contact__ = "brunato@sissa.it"
13
13
  __copyright__ = "Copyright 2018-2025, SISSA"
@@ -7,6 +7,7 @@
7
7
  #
8
8
  # @author Davide Brunato <brunato@sissa.it>
9
9
  #
10
+ from collections import deque
10
11
  from collections.abc import Iterator
11
12
  from typing import cast, Any, Optional, Union
12
13
 
@@ -139,8 +140,8 @@ def build_node_tree(root: ElementTreeRootType,
139
140
  position += 1
140
141
 
141
142
  children = iter(elem)
142
- iterators: list[Any] = []
143
- ancestors: list[Any] = []
143
+ iterators: deque[Any] = deque()
144
+ ancestors: deque[Any] = deque()
144
145
  parent = root_node
145
146
 
146
147
  while True:
@@ -270,8 +271,8 @@ def build_lxml_node_tree(root: LxmlRootType,
270
271
  position += 1
271
272
 
272
273
  children = iter(root_elem)
273
- iterators: list[Any] = []
274
- ancestors: list[Any] = []
274
+ iterators: deque[Any] = deque()
275
+ ancestors: deque[Any] = deque()
275
276
  parent = root_node
276
277
 
277
278
  while True:
@@ -194,6 +194,10 @@ class XPathNode:
194
194
  """Access to wrapped object using the old API."""
195
195
  return self.obj
196
196
 
197
+ @property
198
+ def compat_string_value(self) -> str:
199
+ return self.string_value
200
+
197
201
  @property
198
202
  def root_node(self) -> 'XPathNode':
199
203
  return self if self.parent is None else self.parent.tree.root_node
@@ -1178,10 +1182,14 @@ class EtreeElementNode(ElementNode):
1178
1182
  else:
1179
1183
  yield from get_atomic_sequence(self.xsd_type, '')
1180
1184
 
1185
+ @property
1186
+ def compat_string_value(self) -> str:
1187
+ return ''.join(etree_iter_strings(self.obj))
1188
+
1181
1189
  def apply_schema(self, schema: 'AbstractSchemaProxy') -> None:
1182
- if self.schema is schema and not schema.is_assertion_based():
1190
+ if self.tree.schema is schema and not schema.is_assertion_based():
1183
1191
  return
1184
- self.schema = schema
1192
+ self.tree.schema = schema
1185
1193
 
1186
1194
  if not schema.is_fully_valid():
1187
1195
  element_type = schema.get_type(XSD_ANY_TYPE)
@@ -1214,7 +1222,7 @@ class EtreeElementNode(ElementNode):
1214
1222
  xsd_types = [None]
1215
1223
  children = iter((root_node,))
1216
1224
 
1217
- iterators: list[Any] = []
1225
+ iterators: deque[Any] = deque()
1218
1226
  while True:
1219
1227
  for elem in children:
1220
1228
  if not isinstance(elem, EtreeElementNode):
@@ -1734,6 +1742,12 @@ class EtreeDocumentNode(DocumentNode):
1734
1742
  return ''.join(etree_iter_strings(root))
1735
1743
  return ''.join(child.string_value for child in self.children)
1736
1744
 
1745
+ @property
1746
+ def compat_string_value(self) -> str:
1747
+ if not self.children:
1748
+ return self.string_value
1749
+ return ''.join(child.compat_string_value for child in self.children)
1750
+
1737
1751
  @property
1738
1752
  def is_extended(self) -> bool:
1739
1753
  """
@@ -119,7 +119,7 @@ class XPathToken(Token[XPathTokenType]):
119
119
  if self.symbol == '$':
120
120
  return '$%s variable reference' % (self[0].value if self._items else '')
121
121
  elif self.symbol == ',':
122
- return 'comma operator' if self.parser.version > '1.0' else 'comma symbol'
122
+ return 'comma operator' if self.parser.version != '1.0' else 'comma symbol'
123
123
  elif self.symbol == '(':
124
124
  if not self or self[0].span[0] >= self.span[0]:
125
125
  return 'parenthesized expression'
@@ -434,14 +434,18 @@ class XPathToken(Token[XPathTokenType]):
434
434
  if item is None:
435
435
  return
436
436
  elif isinstance(item, XPathNode):
437
- value = None
438
- for value in item.iter_typed_values:
437
+ if self.parser.version != '1.0':
438
+ value = None
439
+ for value in item.iter_typed_values:
440
+ yield value
441
+
442
+ if value is None:
443
+ msg = f"argument node {item!r} does not have a typed value"
444
+ raise self.error('FOTY0012', msg)
445
+ else:
446
+ value = item.compat_string_value
439
447
  yield value
440
448
 
441
- if value is None:
442
- msg = f"argument node {item!r} does not have a typed value"
443
- raise self.error('FOTY0012', msg)
444
-
445
449
  elif isinstance(item, list):
446
450
  for v in item:
447
451
  yield from self.atomize_item(v)
@@ -913,6 +917,8 @@ class XPathToken(Token[XPathTokenType]):
913
917
  if obj is None:
914
918
  return ''
915
919
  elif isinstance(obj, XPathNode):
920
+ if self.parser.version == '1.0':
921
+ return obj.compat_string_value
916
922
  return obj.string_value
917
923
  elif isinstance(obj, bool):
918
924
  return 'true' if obj else 'false'
@@ -951,7 +957,9 @@ class XPathToken(Token[XPathTokenType]):
951
957
  """
952
958
  try:
953
959
  if isinstance(obj, XPathNode):
954
- return get_double(self.string_value(obj), self.parser.xsd_version)
960
+ if self.parser.version == '1.0':
961
+ return get_double(obj.compat_string_value, self.parser.xsd_version)
962
+ return get_double(obj.string_value, self.parser.xsd_version)
955
963
  else:
956
964
  return get_double(obj, self.parser.xsd_version)
957
965
  except (TypeError, ValueError):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: elementpath
3
- Version: 5.0.2
3
+ Version: 5.0.3
4
4
  Summary: XPath 1.0/2.0/3.0/3.1 parsers and selectors for ElementTree and lxml
5
5
  Author-email: Davide Brunato <brunato@sissa.it>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "elementpath"
7
- version = "5.0.2"
7
+ version = "5.0.3"
8
8
  description = "XPath 1.0/2.0/3.0/3.1 parsers and selectors for ElementTree and lxml"
9
9
  readme = "README.rst"
10
10
  license = "MIT"
@@ -33,6 +33,11 @@ try:
33
33
  except ImportError:
34
34
  lxml_etree = None
35
35
 
36
+ try:
37
+ import xmlschema
38
+ except ImportError:
39
+ xmlschema = None
40
+
36
41
  from elementpath import datatypes, XPath1Parser, XPathContext, MissingContextError, \
37
42
  NamespaceNode, TextNode, CommentNode, ProcessingInstructionNode, select, XPathFunction
38
43
  from elementpath.xpath_nodes import TextAttributeNode, EtreeElementNode
@@ -1719,6 +1724,40 @@ class XPath1ParserTest(xpath_test_class.XPathTestCase):
1719
1724
  token = parser.parse("//eg:q1[1] = //eg:q1[2]")
1720
1725
  self.assertIs(token.evaluate(context), False)
1721
1726
 
1727
+ @unittest.skipIf(xmlschema is None, "XPath schema not available")
1728
+ def test_issue_093_with_schema(self):
1729
+ xml_data = dedent("""\
1730
+ <container xmlns="http://www.w3.org/example">
1731
+ <q1 xmlns:a="http://www.w3.org/test">a:blah</q1>
1732
+ <q1 xmlns:b="http://www.w3.org/test">b:blah</q1>
1733
+ </container>""")
1734
+
1735
+ xsd_schema = dedent("""
1736
+ <schema xmlns="http://www.w3.org/2001/XMLSchema"
1737
+ targetNamespace="http://www.w3.org/example">
1738
+ <element id="container" name="container"/>
1739
+ <element id="q1" name="q1" type="QName"/>
1740
+ </schema>""")
1741
+
1742
+ schema = xmlschema.XMLSchema10(xsd_schema)
1743
+ schema.validate(xml_data)
1744
+
1745
+ resource = xmlschema.XMLResource(xml_data)
1746
+
1747
+ resource.xpath_root.get_document_node(replace=False).apply_schema(schema.xpath_proxy)
1748
+
1749
+ root = self.etree.fromstring(xml_data)
1750
+ namespaces = resource.get_namespaces(root_only=False)
1751
+ context = XPathContext(root, schema=schema.xpath_proxy, namespaces=namespaces)
1752
+
1753
+ parser = self.parser.__class__(namespaces={"eg": "http://www.w3.org/example"})
1754
+ token = parser.parse("//eg:q1[1] = //eg:q1[2]")
1755
+
1756
+ if self.parser.version == "1.0":
1757
+ self.assertIs(token.evaluate(context), False)
1758
+ else:
1759
+ self.assertIs(token.evaluate(context), True)
1760
+
1722
1761
 
1723
1762
  @unittest.skipIf(lxml_etree is None, "The lxml library is not installed")
1724
1763
  class LxmlXPath1ParserTest(XPath1ParserTest):
@@ -334,7 +334,9 @@ class XPath1TokenTest(unittest.TestCase):
334
334
  typed_elem = EtreeElementNode(elem=element)
335
335
  setattr(typed_elem, 'xsd_type', xsd_type)
336
336
  self.assertEqual(token.string_value(typed_elem), '10')
337
- self.assertEqual(token.data_value(typed_elem), 10)
337
+
338
+ value = '10' if self.parser.version == '1.0' else 10
339
+ self.assertEqual(token.data_value(typed_elem), value)
338
340
 
339
341
  def test_number_value_function(self):
340
342
  token = self.parser.parse('true()')
@@ -56,7 +56,7 @@ commands =
56
56
 
57
57
  [testenv:mypy-py{39,310,311,312,313,314,py3}]
58
58
  deps =
59
- mypy==1.16.0
59
+ mypy==1.16.1
60
60
  xmlschema~=4.1.0
61
61
  lxml-stubs
62
62
  commands =
@@ -86,7 +86,7 @@ set_env =
86
86
  xmlschema410: VERSION = 4.1.0
87
87
  change_dir = {env_tmp_dir}
88
88
  deps =
89
- mypy==1.16.0
89
+ mypy==1.16.1
90
90
  lxml
91
91
  lxml-stubs
92
92
  jinja2
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes