Skip to content

Commit 3589c4c

Browse files
authored
Merge pull request #28 from mluis7/pxx-19
pxx-19
2 parents 36248a5 + 5ac4194 commit 3589c4c

File tree

5 files changed

+83
-12
lines changed

5 files changed

+83
-12
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/dist/
22
src/*.egg-info
33
__pycache__/
4+
/.pytest_cache/

.pydevproject

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,34 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
22
<?eclipse-pydev version="1.0"?><pydev_project>
3-
3+
4+
45

56

67
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
7-
8+
9+
810

911
<path>/${PROJECT_DIR_NAME}/src</path>
10-
12+
13+
1114

1215
<path>/${PROJECT_DIR_NAME}/tests</path>
13-
16+
17+
1418

1519
</pydev_pathproperty>
16-
20+
21+
1722

1823

1924
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 3.9</pydev_property>
20-
25+
2126

2227

23-
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">python3.9</pydev_property>
24-
28+
29+
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
30+
31+
2532

2633

2734
</pydev_project>

README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Table of contents
1212
* [Method parse(...)](#method-parse)
1313
* [Print result modes](#print-result-modes)
1414
* [HTML support](#html-support)
15+
* [Relative expressions](#relative-expressions)
1516
* [Unqualified vs. Qualified](#unqualified-vs-qualified)
1617
* [Initial Xpath Examples](#initial-xpath-examples)
1718
* [Performance](#performance)
@@ -215,6 +216,68 @@ or on command line
215216
pyxml2xpath tests/resources/html5-small.html.xml 'all' '//*[@id="math"]'
216217
```
217218

219+
## Relative expressions
220+
Build relative expressions when passing `xpath_base` kword argument. The xpath of the parent should be removed so `base_xpath` should be like:
221+
222+
`xpath_base = '//*[@id="math"]/parent::* | //*[@id="math"]/descendant-or-self::*'`
223+
224+
Example:
225+
226+
```python
227+
from lxml import html
228+
from xml2xpath import xml2xpath
229+
230+
filepath = 'tests/resources/html5-small.html.xml'
231+
hdoc = html.parse(filepath)
232+
233+
needle = 'math'
234+
xpath_base = f'//*[@id="{needle}"]/parent::* | //*[@id="{needle}"]/descendant-or-self::*'
235+
xmap = xml2xpath.parse(None, itree=hdoc, xpath_base=xpath_base)[2]
236+
237+
rel_xpath = []
238+
xiter = iter(xmap)
239+
# parent xpath
240+
x0 = next(xiter)
241+
# base element xpath
242+
x1 = next(xiter)
243+
# get base element attributes and build a predicate with first
244+
x1a = ''
245+
if len(xmap[x1][2]) > 0:
246+
x1a = f'[@{xmap[x1][2][0]}="{needle}"]'
247+
# base element relative xpath (/html/body/math -> //math)
248+
x1f = x1.replace(x0, '/')
249+
# remove numeric indexes if any (div[1] -> div)
250+
x1f = x1f.split('[', 1)[0]
251+
# add first attribute as predicate
252+
x1f += x1a
253+
rel_xpath.append(x1f)
254+
255+
# children relative xpath
256+
for xs in list(xmap.keys())[2:]:
257+
rel_xpath.append(xs.replace(x1, x1f))
258+
259+
for x in rel_xpath:
260+
print(x)
261+
```
262+
263+
Output
264+
265+
```None
266+
//math[@id='math']
267+
//math[@id='math']/mrow
268+
//math[@id='math']/mrow/mi
269+
//math[@id='math']/mrow/mo
270+
//math[@id='math']/mrow/mfrac
271+
//math[@id='math']/mrow/mfrac/mn
272+
//math[@id='math']/mrow/mfrac/msqrt
273+
//math[@id='math']/mrow/mfrac/msqrt/mrow
274+
//math[@id='math']/mrow/mfrac/msqrt/mrow/msup
275+
//math[@id='math']/mrow/mfrac/msqrt/mrow/msup/mi
276+
//math[@id='math']/mrow/mfrac/msqrt/mrow/msup/mn
277+
//math[@id='math']/mrow/mfrac/msqrt/mrow/mo
278+
//math[@id='math']/mrow/mfrac/msqrt/mrow/mn
279+
```
280+
218281
## Unqualified vs. Qualified
219282
Symbolic element tree of `tests/resources/wiki.xml` showing position of unqualified elements.
220283

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.3.3
1+
0.3.4

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ dynamic = ["version"]
99
dependencies = [
1010
"lxml"
1111
]
12-
requires-python = ">=3.9, <=11"
12+
requires-python = ">=3.9"
1313
authors = [
1414
{name = "Luis Muñoz", email = "[email protected]"}
1515
]
1616

17-
description = "Find xpath expressions from XML document."
17+
description = "Generate xpath expressions from XML document."
1818
readme = "README.md"
19-
license = {file = "LICENSE"}
19+
license = {text = "GPL-3.0"}
2020
keywords = ["xpath", "xml"]
2121
classifiers = [
2222
"Development Status :: 5 - Production/Stable",

0 commit comments

Comments
 (0)