elementpath 4.4.0__tar.gz → 4.6.0__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.
- {elementpath-4.4.0 → elementpath-4.6.0}/CHANGELOG.rst +15 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/MANIFEST.in +1 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/PKG-INFO +45 -32
- {elementpath-4.4.0 → elementpath-4.6.0}/README.rst +42 -30
- {elementpath-4.4.0 → elementpath-4.6.0}/doc/conf.py +2 -2
- {elementpath-4.4.0 → elementpath-4.6.0}/doc/xpath_api.rst +3 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/__init__.py +7 -5
- elementpath-4.6.0/elementpath/_typing.py +27 -0
- elementpath-4.6.0/elementpath/aliases.py +43 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/collations.py +3 -3
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/compare.py +10 -9
- elementpath-4.6.0/elementpath/datatypes/__init__.py +61 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/atomic_types.py +8 -2
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/binary.py +2 -2
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/datetime.py +17 -10
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/numeric.py +6 -3
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/proxies.py +13 -1
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/qname.py +5 -2
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/string.py +7 -4
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/untyped.py +1 -1
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/uri.py +2 -2
- elementpath-4.6.0/elementpath/decoder.py +176 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/etree.py +4 -3
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/exceptions.py +13 -7
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/helpers.py +71 -23
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/namespaces.py +37 -39
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/protocols.py +52 -6
- elementpath-4.6.0/elementpath/regex/__init__.py +25 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/regex/character_classes.py +59 -44
- elementpath-4.6.0/elementpath/regex/codepoints.py +206 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/regex/patterns.py +7 -7
- elementpath-4.6.0/elementpath/regex/unicode_blocks.py +450 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/regex/unicode_categories.py +418 -5
- elementpath-4.6.0/elementpath/regex/unicode_subsets.py +639 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/schema_proxy.py +11 -15
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/sequence_types.py +16 -18
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/serialization.py +9 -7
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/tdop.py +25 -21
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/tree_builders.py +160 -146
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/validators/__init__.py +1 -1
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath1/_xpath1_axes.py +39 -24
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath1/_xpath1_functions.py +90 -63
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath1/_xpath1_operators.py +173 -174
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath1/xpath1_parser.py +88 -27
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath2/_xpath2_constructors.py +147 -89
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath2/_xpath2_functions.py +318 -230
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath2/_xpath2_operators.py +145 -102
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath2/xpath2_parser.py +33 -45
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath30/_xpath30_functions.py +240 -163
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath30/_xpath30_operators.py +45 -23
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath30/xpath30_helpers.py +4 -3
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath30/xpath30_parser.py +3 -4
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath31/_xpath31_functions.py +196 -144
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath31/_xpath31_operators.py +41 -27
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath31/xpath31_parser.py +3 -3
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath_context.py +96 -59
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath_nodes.py +73 -48
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath_selectors.py +10 -14
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath_tokens.py +238 -246
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath.egg-info/PKG-INFO +45 -32
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath.egg-info/SOURCES.txt +6 -1
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath.egg-info/requires.txt +1 -1
- {elementpath-4.4.0 → elementpath-4.6.0}/requirements-dev.txt +1 -1
- elementpath-4.6.0/scripts/generate_codepoints.py +406 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/setup.py +3 -2
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/execute_w3c_tests.py +4 -1
- elementpath-4.6.0/tests/mypy_tests/advanced.py +30 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/mypy_tests/selectors.py +15 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_datatypes.py +5 -4
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_helpers.py +15 -2
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_regex.py +225 -51
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_selectors.py +22 -1
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_tree_builders.py +67 -3
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_typing.py +8 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath1_parser.py +23 -18
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath2_constructors.py +4 -2
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath2_functions.py +10 -5
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath2_parser.py +109 -2
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath30.py +21 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath_context.py +1 -4
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath_nodes.py +23 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath_tokens.py +40 -75
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/xpath_test_class.py +2 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tox.ini +29 -17
- elementpath-4.4.0/elementpath/datatypes/__init__.py +0 -124
- elementpath-4.4.0/elementpath/regex/__init__.py +0 -24
- elementpath-4.4.0/elementpath/regex/codepoints.py +0 -124
- elementpath-4.4.0/elementpath/regex/generate_categories.py +0 -116
- elementpath-4.4.0/elementpath/regex/unicode_subsets.py +0 -518
- {elementpath-4.4.0 → elementpath-4.6.0}/.coveragerc +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/LICENSE +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/doc/Makefile +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/doc/advanced.rst +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/doc/index.rst +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/doc/introduction.rst +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/doc/make.bat +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/doc/pratt_api.rst +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/doc/requirements.txt +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/py.typed +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/validators/analyze-string.xsd +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/validators/schema-for-json.xsd +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath1/__init__.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath2/__init__.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath3.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath30/__init__.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath30/_translation_maps.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath31/__init__.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath.egg-info/dependency_links.txt +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/elementpath.egg-info/top_level.txt +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/mypy.ini +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/setup.cfg +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/__init__.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/memory_profiling.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/mypy_tests/protocols.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/resources/analyze-string.xsd +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/resources/external_entity.xml +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/resources/sample.xml +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/resources/schema-for-json.xsd +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/resources/unparsed_entity.xml +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/resources/unused_external_entity.xml +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/resources/unused_unparsed_entity.xml +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/resources/with_entity.xml +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_collations.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_compare.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_elementpath.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_etree.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_exceptions.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_namespaces.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_package.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_schema_context.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_schema_proxy.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_sequence_types.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_serialization.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_tdop_parser.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_validators.py +0 -0
- {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath31.py +0 -0
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
CHANGELOG
|
|
3
3
|
*********
|
|
4
4
|
|
|
5
|
+
`v4.6.0`_ (2024-10-27)
|
|
6
|
+
======================
|
|
7
|
+
* Fix XsdAttributeGroupProtocol
|
|
8
|
+
* Improve Unicode support with installable UnicodeData.txt versions
|
|
9
|
+
* Extend names disambiguation with a fix for issue #78
|
|
10
|
+
* Refactor tree builders to fix document position of tails (issue #79)
|
|
11
|
+
|
|
12
|
+
`v4.5.0`_ (2024-09-09)
|
|
13
|
+
======================
|
|
14
|
+
* Fix and clean node trees iteration methods (issue #72)
|
|
15
|
+
* Fix missing raw string for '[^\r\n]' (pull request #76)
|
|
16
|
+
* Full and more specific type annotations
|
|
17
|
+
|
|
5
18
|
`v4.4.0`_ (2024-03-11)
|
|
6
19
|
======================
|
|
7
20
|
* Improve stand-alone XPath functions builder (issue #70)
|
|
@@ -463,3 +476,5 @@ CHANGELOG
|
|
|
463
476
|
.. _v4.2.1: https://github.com/sissaschool/elementpath/compare/v4.2.0...v4.2.1
|
|
464
477
|
.. _v4.3.0: https://github.com/sissaschool/elementpath/compare/v4.2.1...v4.3.0
|
|
465
478
|
.. _v4.4.0: https://github.com/sissaschool/elementpath/compare/v4.3.0...v4.4.0
|
|
479
|
+
.. _v4.5.0: https://github.com/sissaschool/elementpath/compare/v4.4.0...v4.5.0
|
|
480
|
+
.. _v4.6.0: https://github.com/sissaschool/elementpath/compare/v4.5.0...v4.6.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: elementpath
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.6.0
|
|
4
4
|
Summary: XPath 1.0/2.0/3.0/3.1 parsers and selectors for ElementTree and lxml
|
|
5
5
|
Home-page: https://github.com/sissaschool/elementpath
|
|
6
6
|
Author: Davide Brunato
|
|
@@ -22,6 +22,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.11
|
|
23
23
|
Classifier: Programming Language :: Python :: 3.12
|
|
24
24
|
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
25
26
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
26
27
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
27
28
|
Classifier: Topic :: Software Development :: Libraries
|
|
@@ -32,7 +33,7 @@ Provides-Extra: dev
|
|
|
32
33
|
Requires-Dist: tox; extra == "dev"
|
|
33
34
|
Requires-Dist: coverage; extra == "dev"
|
|
34
35
|
Requires-Dist: lxml; extra == "dev"
|
|
35
|
-
Requires-Dist: xmlschema>=
|
|
36
|
+
Requires-Dist: xmlschema>=3.3.2; extra == "dev"
|
|
36
37
|
Requires-Dist: Sphinx; extra == "dev"
|
|
37
38
|
Requires-Dist: memory-profiler; extra == "dev"
|
|
38
39
|
Requires-Dist: memray; extra == "dev"
|
|
@@ -76,11 +77,13 @@ You can install the package with *pip* in a Python 3.8+ environment::
|
|
|
76
77
|
|
|
77
78
|
For using it import the package and apply the selectors on ElementTree nodes:
|
|
78
79
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
>>>
|
|
82
|
-
>>>
|
|
83
|
-
|
|
80
|
+
.. code-block:: pycon
|
|
81
|
+
|
|
82
|
+
>>> import elementpath
|
|
83
|
+
>>> from xml.etree import ElementTree
|
|
84
|
+
>>> root = ElementTree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
|
|
85
|
+
>>> elementpath.select(root, '/A/B2/*')
|
|
86
|
+
[<Element 'C1' at ...>, <Element 'C2' at ...>, <Element 'C3' at ...>]
|
|
84
87
|
|
|
85
88
|
The *select* API provides the standard XPath result format that is a list or an elementary
|
|
86
89
|
datatype's value. If you want only to iterate over results you can use the generator function
|
|
@@ -89,52 +92,62 @@ datatype's value. If you want only to iterate over results you can use the gener
|
|
|
89
92
|
The selectors API works also using XML data trees based on the `lxml.etree <http://lxml.de>`_
|
|
90
93
|
library:
|
|
91
94
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
>>>
|
|
95
|
-
>>>
|
|
96
|
-
|
|
95
|
+
.. code-block:: pycon
|
|
96
|
+
|
|
97
|
+
>>> import elementpath
|
|
98
|
+
>>> import lxml.etree as etree
|
|
99
|
+
>>> root = etree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
|
|
100
|
+
>>> elementpath.select(root, '/A/B2/*')
|
|
101
|
+
[<Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
|
|
97
102
|
|
|
98
103
|
When you need to apply the same XPath expression to several XML data you can also use the
|
|
99
104
|
*Selector* class, creating an instance and then using it to apply the path on distinct XML
|
|
100
105
|
data:
|
|
101
106
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
>>>
|
|
105
|
-
>>>
|
|
106
|
-
>>> selector.
|
|
107
|
-
|
|
108
|
-
>>>
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
.. code-block:: pycon
|
|
108
|
+
|
|
109
|
+
>>> import elementpath
|
|
110
|
+
>>> import lxml.etree as etree
|
|
111
|
+
>>> selector = elementpath.Selector('/A/*/*')
|
|
112
|
+
>>> root = etree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
|
|
113
|
+
>>> selector.select(root)
|
|
114
|
+
[<Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
|
|
115
|
+
>>> root = etree.XML('<A><B1><C0/></B1><B2><C1/><C2/><C3/></B2></A>')
|
|
116
|
+
>>> selector.select(root)
|
|
117
|
+
[<Element C0 at ...>, <Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
|
|
111
118
|
|
|
112
119
|
Public API classes and functions are described into the
|
|
113
120
|
`elementpath manual on the "Read the Docs" site <http://elementpath.readthedocs.io/en/latest/>`_.
|
|
114
121
|
|
|
115
122
|
For default the XPath 2.0 is used. If you need XPath 1.0 parser provide the *parser* argument:
|
|
116
123
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
>>>
|
|
120
|
-
>>>
|
|
121
|
-
|
|
124
|
+
.. code-block:: pycon
|
|
125
|
+
|
|
126
|
+
>>> from elementpath import select, XPath1Parser
|
|
127
|
+
>>> from xml.etree import ElementTree
|
|
128
|
+
>>> root = ElementTree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
|
|
129
|
+
>>> select(root, '/A/B2/*', parser=XPath1Parser)
|
|
130
|
+
[<Element 'C1' at ...>, <Element 'C2' at ...>, <Element 'C3' at ...>]
|
|
122
131
|
|
|
123
132
|
For XPath 3.0/3.1 import the parser from *elementpath.xpath3* subpackage, that is not loaded
|
|
124
133
|
for default:
|
|
125
134
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
135
|
+
.. code-block:: pycon
|
|
136
|
+
|
|
137
|
+
>>> from elementpath.xpath3 import XPath3Parser
|
|
138
|
+
>>> select(root, 'math:atan(1.0e0)', parser=XPath3Parser)
|
|
139
|
+
0.7853981633974483
|
|
129
140
|
|
|
130
141
|
Note: *XPath3Parser* is an alias of *XPath31Parser*.
|
|
131
142
|
|
|
132
143
|
If you need only XPath 3.0 you can also use a more specific subpackage,
|
|
133
144
|
avoiding the loading of XPath 3.1 implementation:
|
|
134
145
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
146
|
+
.. code-block:: pycon
|
|
147
|
+
|
|
148
|
+
>>> from elementpath.xpath30 import XPath30Parser
|
|
149
|
+
>>> select(root, 'math:atan(1.0e0)', parser=XPath30Parser)
|
|
150
|
+
0.7853981633974483
|
|
138
151
|
|
|
139
152
|
|
|
140
153
|
Contributing
|
|
@@ -34,11 +34,13 @@ You can install the package with *pip* in a Python 3.8+ environment::
|
|
|
34
34
|
|
|
35
35
|
For using it import the package and apply the selectors on ElementTree nodes:
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
>>>
|
|
40
|
-
>>>
|
|
41
|
-
|
|
37
|
+
.. code-block:: pycon
|
|
38
|
+
|
|
39
|
+
>>> import elementpath
|
|
40
|
+
>>> from xml.etree import ElementTree
|
|
41
|
+
>>> root = ElementTree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
|
|
42
|
+
>>> elementpath.select(root, '/A/B2/*')
|
|
43
|
+
[<Element 'C1' at ...>, <Element 'C2' at ...>, <Element 'C3' at ...>]
|
|
42
44
|
|
|
43
45
|
The *select* API provides the standard XPath result format that is a list or an elementary
|
|
44
46
|
datatype's value. If you want only to iterate over results you can use the generator function
|
|
@@ -47,52 +49,62 @@ datatype's value. If you want only to iterate over results you can use the gener
|
|
|
47
49
|
The selectors API works also using XML data trees based on the `lxml.etree <http://lxml.de>`_
|
|
48
50
|
library:
|
|
49
51
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
>>>
|
|
53
|
-
>>>
|
|
54
|
-
|
|
52
|
+
.. code-block:: pycon
|
|
53
|
+
|
|
54
|
+
>>> import elementpath
|
|
55
|
+
>>> import lxml.etree as etree
|
|
56
|
+
>>> root = etree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
|
|
57
|
+
>>> elementpath.select(root, '/A/B2/*')
|
|
58
|
+
[<Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
|
|
55
59
|
|
|
56
60
|
When you need to apply the same XPath expression to several XML data you can also use the
|
|
57
61
|
*Selector* class, creating an instance and then using it to apply the path on distinct XML
|
|
58
62
|
data:
|
|
59
63
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
>>>
|
|
63
|
-
>>>
|
|
64
|
-
>>> selector.
|
|
65
|
-
|
|
66
|
-
>>>
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
.. code-block:: pycon
|
|
65
|
+
|
|
66
|
+
>>> import elementpath
|
|
67
|
+
>>> import lxml.etree as etree
|
|
68
|
+
>>> selector = elementpath.Selector('/A/*/*')
|
|
69
|
+
>>> root = etree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
|
|
70
|
+
>>> selector.select(root)
|
|
71
|
+
[<Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
|
|
72
|
+
>>> root = etree.XML('<A><B1><C0/></B1><B2><C1/><C2/><C3/></B2></A>')
|
|
73
|
+
>>> selector.select(root)
|
|
74
|
+
[<Element C0 at ...>, <Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
|
|
69
75
|
|
|
70
76
|
Public API classes and functions are described into the
|
|
71
77
|
`elementpath manual on the "Read the Docs" site <http://elementpath.readthedocs.io/en/latest/>`_.
|
|
72
78
|
|
|
73
79
|
For default the XPath 2.0 is used. If you need XPath 1.0 parser provide the *parser* argument:
|
|
74
80
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
>>>
|
|
78
|
-
>>>
|
|
79
|
-
|
|
81
|
+
.. code-block:: pycon
|
|
82
|
+
|
|
83
|
+
>>> from elementpath import select, XPath1Parser
|
|
84
|
+
>>> from xml.etree import ElementTree
|
|
85
|
+
>>> root = ElementTree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
|
|
86
|
+
>>> select(root, '/A/B2/*', parser=XPath1Parser)
|
|
87
|
+
[<Element 'C1' at ...>, <Element 'C2' at ...>, <Element 'C3' at ...>]
|
|
80
88
|
|
|
81
89
|
For XPath 3.0/3.1 import the parser from *elementpath.xpath3* subpackage, that is not loaded
|
|
82
90
|
for default:
|
|
83
91
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
92
|
+
.. code-block:: pycon
|
|
93
|
+
|
|
94
|
+
>>> from elementpath.xpath3 import XPath3Parser
|
|
95
|
+
>>> select(root, 'math:atan(1.0e0)', parser=XPath3Parser)
|
|
96
|
+
0.7853981633974483
|
|
87
97
|
|
|
88
98
|
Note: *XPath3Parser* is an alias of *XPath31Parser*.
|
|
89
99
|
|
|
90
100
|
If you need only XPath 3.0 you can also use a more specific subpackage,
|
|
91
101
|
avoiding the loading of XPath 3.1 implementation:
|
|
92
102
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
103
|
+
.. code-block:: pycon
|
|
104
|
+
|
|
105
|
+
>>> from elementpath.xpath30 import XPath30Parser
|
|
106
|
+
>>> select(root, 'math:atan(1.0e0)', parser=XPath30Parser)
|
|
107
|
+
0.7853981633974483
|
|
96
108
|
|
|
97
109
|
|
|
98
110
|
Contributing
|
|
@@ -29,9 +29,9 @@ copyright = '2018-2024, SISSA (International School for Advanced Studies)'
|
|
|
29
29
|
author = 'Davide Brunato'
|
|
30
30
|
|
|
31
31
|
# The short X.Y version
|
|
32
|
-
version = '4.
|
|
32
|
+
version = '4.6'
|
|
33
33
|
# The full version, including alpha/beta/rc tags
|
|
34
|
-
release = '4.
|
|
34
|
+
release = '4.6.0'
|
|
35
35
|
|
|
36
36
|
# -- General configuration ---------------------------------------------------
|
|
37
37
|
|
|
@@ -147,6 +147,8 @@ XPath regular expressions
|
|
|
147
147
|
=========================
|
|
148
148
|
|
|
149
149
|
.. autofunction:: elementpath.translate_pattern
|
|
150
|
+
.. autofunction:: elementpath.install_unicode_data
|
|
151
|
+
.. autofunction:: elementpath.unicode_version
|
|
150
152
|
|
|
151
153
|
|
|
152
154
|
Exception classes
|
|
@@ -154,6 +156,7 @@ Exception classes
|
|
|
154
156
|
|
|
155
157
|
.. autoexception:: elementpath.ElementPathError
|
|
156
158
|
.. autoexception:: elementpath.MissingContextError
|
|
159
|
+
.. autoexception:: elementpath.UnsupportedFeatureError
|
|
157
160
|
.. autoexception:: elementpath.RegexError
|
|
158
161
|
.. autoexception:: elementpath.ElementPathLocaleError
|
|
159
162
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
#
|
|
8
8
|
# @author Davide Brunato <brunato@sissa.it>
|
|
9
9
|
#
|
|
10
|
-
__version__ = '4.
|
|
10
|
+
__version__ = '4.6.0'
|
|
11
11
|
__author__ = "Davide Brunato"
|
|
12
12
|
__contact__ = "brunato@sissa.it"
|
|
13
13
|
__copyright__ = "Copyright 2018-2024, SISSA"
|
|
@@ -23,7 +23,7 @@ from . import protocols # Protocols for type annotations
|
|
|
23
23
|
from .exceptions import ElementPathError, MissingContextError, ElementPathKeyError, \
|
|
24
24
|
ElementPathZeroDivisionError, ElementPathNameError, ElementPathOverflowError, \
|
|
25
25
|
ElementPathRuntimeError, ElementPathSyntaxError, ElementPathTypeError, \
|
|
26
|
-
ElementPathValueError, ElementPathLocaleError
|
|
26
|
+
ElementPathValueError, ElementPathLocaleError, UnsupportedFeatureError
|
|
27
27
|
|
|
28
28
|
from .xpath_context import XPathContext, XPathSchemaContext
|
|
29
29
|
from .xpath_nodes import XPathNode, DocumentNode, ElementNode, AttributeNode, \
|
|
@@ -36,10 +36,11 @@ from .xpath1 import XPath1Parser
|
|
|
36
36
|
from .xpath2 import XPath2Parser
|
|
37
37
|
from .xpath_selectors import select, iter_select, Selector
|
|
38
38
|
from .schema_proxy import AbstractSchemaProxy
|
|
39
|
-
from .regex import RegexError, translate_pattern
|
|
39
|
+
from .regex import RegexError, translate_pattern, install_unicode_data, unicode_version
|
|
40
40
|
|
|
41
41
|
__all__ = ['datatypes', 'protocols', 'etree', 'ElementPathError', 'MissingContextError',
|
|
42
|
-
'
|
|
42
|
+
'UnsupportedFeatureError', 'ElementPathKeyError',
|
|
43
|
+
'ElementPathZeroDivisionError', 'ElementPathNameError',
|
|
43
44
|
'ElementPathOverflowError', 'ElementPathRuntimeError', 'ElementPathSyntaxError',
|
|
44
45
|
'ElementPathTypeError', 'ElementPathValueError', 'ElementPathLocaleError',
|
|
45
46
|
'XPathContext', 'XPathSchemaContext', 'XPathNode', 'DocumentNode',
|
|
@@ -48,4 +49,5 @@ __all__ = ['datatypes', 'protocols', 'etree', 'ElementPathError', 'MissingContex
|
|
|
48
49
|
'SchemaElementNode', 'get_node_tree', 'build_node_tree',
|
|
49
50
|
'build_lxml_node_tree', 'build_schema_node_tree', 'XPathToken',
|
|
50
51
|
'XPathFunction', 'XPath1Parser', 'XPath2Parser', 'select', 'iter_select',
|
|
51
|
-
'Selector', 'AbstractSchemaProxy', 'RegexError', 'translate_pattern'
|
|
52
|
+
'Selector', 'AbstractSchemaProxy', 'RegexError', 'translate_pattern',
|
|
53
|
+
'install_unicode_data', 'unicode_version']
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c), 2024, SISSA (International School for Advanced Studies).
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
# This file is distributed under the terms of the MIT License.
|
|
5
|
+
# See the file 'LICENSE' in the root directory of the present
|
|
6
|
+
# distribution, or http://opensource.org/licenses/MIT.
|
|
7
|
+
#
|
|
8
|
+
# @author Davide Brunato <brunato@sissa.it>
|
|
9
|
+
#
|
|
10
|
+
"""
|
|
11
|
+
Version related imports for subscriptable types for type annotations (no builtins).
|
|
12
|
+
"""
|
|
13
|
+
import sys
|
|
14
|
+
|
|
15
|
+
if sys.version_info < (3, 9):
|
|
16
|
+
from typing import Callable, Counter, Deque, Iterable, Iterator, \
|
|
17
|
+
Mapping, Match, MutableMapping, MutableSequence, MutableSet, Pattern, Sequence
|
|
18
|
+
else:
|
|
19
|
+
from collections import deque as Deque, Counter # noqa
|
|
20
|
+
from collections.abc import Callable, Iterable, Iterator, Mapping, MutableMapping, \
|
|
21
|
+
MutableSequence, MutableSet, Sequence
|
|
22
|
+
from re import Match, Pattern
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
__all__ = ['Callable', 'Counter', 'Deque', 'Iterable', 'Iterator', 'Match',
|
|
26
|
+
'Mapping', 'MutableMapping', 'MutableSequence', 'MutableSet',
|
|
27
|
+
'Pattern', 'Sequence']
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c), 2021, SISSA (International School for Advanced Studies).
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
# This file is distributed under the terms of the MIT License.
|
|
5
|
+
# See the file 'LICENSE' in the root directory of the present
|
|
6
|
+
# distribution, or http://opensource.org/licenses/MIT.
|
|
7
|
+
#
|
|
8
|
+
# @author Davide Brunato <brunato@sissa.it>
|
|
9
|
+
#
|
|
10
|
+
"""
|
|
11
|
+
Common type hints aliases for elementpath.
|
|
12
|
+
"""
|
|
13
|
+
from typing import Any, List, Optional, NoReturn, Tuple, Type, TYPE_CHECKING, TypeVar, Union
|
|
14
|
+
|
|
15
|
+
from elementpath._typing import MutableMapping
|
|
16
|
+
|
|
17
|
+
##
|
|
18
|
+
# Type aliases
|
|
19
|
+
NamespacesType = MutableMapping[str, str]
|
|
20
|
+
NsmapType = MutableMapping[Optional[str], str] # compatible with the nsmap of lxml Element
|
|
21
|
+
AnyNsmapType = Union[NamespacesType, NsmapType, None] # for composition and function arguments
|
|
22
|
+
|
|
23
|
+
NargsType = Optional[Union[int, Tuple[int, Optional[int]]]]
|
|
24
|
+
ClassCheckType = Union[Type[Any], Tuple[Type[Any], ...]]
|
|
25
|
+
|
|
26
|
+
T = TypeVar('T')
|
|
27
|
+
Emptiable = Union[T, List[NoReturn]]
|
|
28
|
+
SequenceType = Union[T, List[T]]
|
|
29
|
+
InputType = Union[None, T, List[T], Tuple[T, ...]]
|
|
30
|
+
|
|
31
|
+
if TYPE_CHECKING:
|
|
32
|
+
from elementpath.datatypes import AtomicType, ArithmeticType, NumericType
|
|
33
|
+
from elementpath.xpath_nodes import ChildNodeType, ParentNodeType
|
|
34
|
+
from elementpath.tree_builders import RootArgType
|
|
35
|
+
from elementpath.xpath_context import ContextType, FunctionArgType, ItemType, \
|
|
36
|
+
ItemArgType, ValueType
|
|
37
|
+
from elementpath.xpath_tokens import XPathParserType, XPathTokenType
|
|
38
|
+
|
|
39
|
+
__all__ = ['NamespacesType', 'NsmapType', 'AnyNsmapType', 'NargsType',
|
|
40
|
+
'ClassCheckType', 'Emptiable', 'SequenceType', 'InputType',
|
|
41
|
+
'AtomicType', 'ArithmeticType', 'NumericType', 'ChildNodeType',
|
|
42
|
+
'ParentNodeType', 'RootArgType', 'ContextType', 'FunctionArgType',
|
|
43
|
+
'ItemType', 'ItemArgType', 'ValueType', 'XPathParserType', 'XPathTokenType']
|
|
@@ -14,7 +14,7 @@ from types import TracebackType
|
|
|
14
14
|
from typing import TYPE_CHECKING, Any, Optional, Tuple, Type, Union
|
|
15
15
|
from urllib.parse import urljoin, urlsplit
|
|
16
16
|
|
|
17
|
-
from .exceptions import xpath_error
|
|
17
|
+
from elementpath.exceptions import xpath_error
|
|
18
18
|
|
|
19
19
|
if TYPE_CHECKING:
|
|
20
20
|
from .xpath_tokens import XPathToken
|
|
@@ -173,8 +173,8 @@ class CollationManager(context_class_base):
|
|
|
173
173
|
def find(self, a: str, b: str) -> int:
|
|
174
174
|
return self.strxfrm(a).find(self.strxfrm(b))
|
|
175
175
|
|
|
176
|
-
def startswith(self, a: str, b: str) ->
|
|
176
|
+
def startswith(self, a: str, b: str) -> bool:
|
|
177
177
|
return self.strxfrm(a).startswith(self.strxfrm(b))
|
|
178
178
|
|
|
179
|
-
def endswith(self, a: str, b: str) ->
|
|
179
|
+
def endswith(self, a: str, b: str) -> bool:
|
|
180
180
|
return self.strxfrm(a).endswith(self.strxfrm(b))
|
|
@@ -11,15 +11,16 @@ import math
|
|
|
11
11
|
from decimal import Decimal
|
|
12
12
|
from functools import cmp_to_key
|
|
13
13
|
from itertools import zip_longest
|
|
14
|
-
from typing import Any,
|
|
15
|
-
|
|
16
|
-
from .
|
|
17
|
-
from .
|
|
18
|
-
from .
|
|
19
|
-
from .
|
|
20
|
-
from .
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
from typing import Any, Optional
|
|
15
|
+
|
|
16
|
+
from elementpath._typing import Callable, Iterable, Iterator
|
|
17
|
+
from elementpath.protocols import ElementProtocol
|
|
18
|
+
from elementpath.exceptions import xpath_error
|
|
19
|
+
from elementpath.datatypes import UntypedAtomic, AnyURI, AbstractQName
|
|
20
|
+
from elementpath.collations import UNICODE_CODEPOINT_COLLATION, CollationManager
|
|
21
|
+
from elementpath.xpath_nodes import XPathNode, ElementNode, AttributeNode, \
|
|
22
|
+
NamespaceNode, TextNode, CommentNode, ProcessingInstructionNode, DocumentNode
|
|
23
|
+
from elementpath.xpath_tokens import XPathToken, XPathFunction, XPathMap, XPathArray
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
def deep_equal(seq1: Iterable[Any],
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c), 2018-2020, SISSA (International School for Advanced Studies).
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
# This file is distributed under the terms of the MIT License.
|
|
5
|
+
# See the file 'LICENSE' in the root directory of the present
|
|
6
|
+
# distribution, or http://opensource.org/licenses/MIT.
|
|
7
|
+
#
|
|
8
|
+
# @author Davide Brunato <brunato@sissa.it>
|
|
9
|
+
#
|
|
10
|
+
"""
|
|
11
|
+
XSD atomic datatypes subpackage. Includes a class for UntypedAtomic data and
|
|
12
|
+
classes for other XSD built-in types. This subpackage raises only built-in
|
|
13
|
+
exceptions in order to be reusable in other packages.
|
|
14
|
+
"""
|
|
15
|
+
from decimal import Decimal
|
|
16
|
+
from typing import Union
|
|
17
|
+
|
|
18
|
+
from .atomic_types import xsd10_atomic_types, xsd11_atomic_types, \
|
|
19
|
+
AtomicTypeMeta, AnyAtomicType
|
|
20
|
+
from .untyped import UntypedAtomic
|
|
21
|
+
from .qname import AbstractQName, QName, Notation
|
|
22
|
+
from .numeric import Float10, Float, Integer, Int, NegativeInteger, \
|
|
23
|
+
PositiveInteger, NonNegativeInteger, NonPositiveInteger, Long, \
|
|
24
|
+
Short, Byte, UnsignedByte, UnsignedInt, UnsignedLong, UnsignedShort
|
|
25
|
+
from .string import NormalizedString, XsdToken, Name, NCName, NMToken, Id, \
|
|
26
|
+
Idref, Language, Entity
|
|
27
|
+
from .uri import AnyURI
|
|
28
|
+
from .binary import AbstractBinary, Base64Binary, HexBinary
|
|
29
|
+
from .datetime import AbstractDateTime, DateTime10, DateTime, DateTimeStamp, \
|
|
30
|
+
Date10, Date, GregorianDay, GregorianMonth, GregorianYear, GregorianYear10, \
|
|
31
|
+
GregorianMonthDay, GregorianYearMonth, GregorianYearMonth10, Time, Timezone, \
|
|
32
|
+
Duration, DayTimeDuration, YearMonthDuration, OrderedDateTime
|
|
33
|
+
from .proxies import BooleanProxy, DecimalProxy, DoubleProxy10, DoubleProxy, \
|
|
34
|
+
StringProxy, NumericProxy, ArithmeticProxy
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
xsd11_atomic_types.update(
|
|
38
|
+
(k, v) for k, v in xsd10_atomic_types.items() if k not in xsd11_atomic_types
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
###
|
|
42
|
+
# Aliases for type annotations
|
|
43
|
+
AtomicType = Union[str, int, float, Decimal, bool, AnyAtomicType]
|
|
44
|
+
NumericType = Union[int, float, Decimal]
|
|
45
|
+
ArithmeticType = Union[NumericType, AbstractDateTime, Duration, UntypedAtomic]
|
|
46
|
+
DatetimeValueType = AbstractDateTime # keep until v5.0 for backward compatibility
|
|
47
|
+
|
|
48
|
+
__all__ = ['xsd10_atomic_types', 'xsd11_atomic_types',
|
|
49
|
+
'AtomicTypeMeta', 'AnyAtomicType', 'NumericProxy', 'ArithmeticProxy',
|
|
50
|
+
'AbstractDateTime', 'DateTime10', 'DateTime', 'DateTimeStamp', 'Date10',
|
|
51
|
+
'Date', 'Time', 'GregorianDay', 'GregorianMonth', 'GregorianMonthDay',
|
|
52
|
+
'GregorianYear10', 'GregorianYear', 'GregorianYearMonth10', 'GregorianYearMonth',
|
|
53
|
+
'Timezone', 'Duration', 'YearMonthDuration', 'DayTimeDuration', 'StringProxy',
|
|
54
|
+
'NormalizedString', 'XsdToken', 'Language', 'Name', 'NCName', 'Id', 'Idref',
|
|
55
|
+
'Entity', 'NMToken', 'Base64Binary', 'HexBinary', 'Float10', 'Float',
|
|
56
|
+
'Integer', 'NonPositiveInteger', 'NegativeInteger', 'Long', 'Int', 'Short',
|
|
57
|
+
'Byte', 'NonNegativeInteger', 'PositiveInteger', 'UnsignedLong', 'UnsignedInt',
|
|
58
|
+
'UnsignedShort', 'UnsignedByte', 'AnyURI', 'Notation', 'QName', 'BooleanProxy',
|
|
59
|
+
'DecimalProxy', 'DoubleProxy10', 'DoubleProxy', 'UntypedAtomic', 'AbstractBinary',
|
|
60
|
+
'AtomicType', 'DatetimeValueType', 'OrderedDateTime', 'AbstractQName',
|
|
61
|
+
'NumericType', 'ArithmeticType']
|
|
@@ -7,10 +7,12 @@
|
|
|
7
7
|
#
|
|
8
8
|
# @author Davide Brunato <brunato@sissa.it>
|
|
9
9
|
#
|
|
10
|
-
from abc import ABCMeta
|
|
11
|
-
from typing import Any, Dict, Optional,
|
|
10
|
+
from abc import ABCMeta, abstractmethod
|
|
11
|
+
from typing import Any, Dict, Optional, Tuple, Type
|
|
12
12
|
import re
|
|
13
13
|
|
|
14
|
+
from elementpath._typing import Pattern
|
|
15
|
+
|
|
14
16
|
XSD_NAMESPACE = "http://www.w3.org/2001/XMLSchema"
|
|
15
17
|
|
|
16
18
|
###
|
|
@@ -98,3 +100,7 @@ class AtomicTypeMeta(ABCMeta):
|
|
|
98
100
|
|
|
99
101
|
class AnyAtomicType(metaclass=AtomicTypeMeta):
|
|
100
102
|
name = 'anyAtomicType'
|
|
103
|
+
|
|
104
|
+
@abstractmethod
|
|
105
|
+
def __init__(self, value: Any) -> None:
|
|
106
|
+
raise NotImplementedError()
|
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
#
|
|
8
8
|
# @author Davide Brunato <brunato@sissa.it>
|
|
9
9
|
#
|
|
10
|
+
import re
|
|
10
11
|
from abc import abstractmethod
|
|
11
12
|
from typing import Any, Callable, Union
|
|
12
|
-
import re
|
|
13
13
|
import codecs
|
|
14
14
|
|
|
15
|
-
from
|
|
15
|
+
from elementpath.helpers import collapse_white_spaces
|
|
16
16
|
from .atomic_types import AnyAtomicType
|
|
17
17
|
from .untyped import UntypedAtomic
|
|
18
18
|
|