Repository: tefra/xsdata
Pull request #531 (2021-06-17 16:24:50)

LxmlEventHandler: support lxml Element or Tree as source
Support parsing from a subtree

```python

import lxml

from xsdata.formats.dataclass.parsers import XmlParser
from xsdata.formats.dataclass.parsers.handlers import LxmlEventHandler

tree = lxml.etree.parse("/tmp/sample.xml")
parser = XmlParser(handler=LxmlEventHandler)
parser.parse(tree.find('.//{some}path'), SomeModel)
```

- [x] Support element or tree in the lxml default handler
- [ ] Check if the native python xml has anything similar to lxml iterwalk api
- [x] Tests

sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=BUG)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=VULNERABILITY)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=531&resolved=false&types=SECURITY_HOTSPOT) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=531&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=531&resolved=false&types=SECURITY_HOTSPOT)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=CODE_SMELL)

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo.png' alt='No Coverage information' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=531) No Coverage information  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='0.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=531&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=531&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=BUG)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=VULNERABILITY)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=531&resolved=false&types=SECURITY_HOTSPOT) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=531&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=531&resolved=false&types=SECURITY_HOTSPOT)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=CODE_SMELL)

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo.png' alt='No Coverage information' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=531) No Coverage information  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='0.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=531&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=531&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=BUG)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=VULNERABILITY)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=531&resolved=false&types=SECURITY_HOTSPOT) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=531&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=531&resolved=false&types=SECURITY_HOTSPOT)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=CODE_SMELL)

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo.png' alt='No Coverage information' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=531) No Coverage information  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='0.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=531&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=531&metric=new_duplicated_lines_density&view=list)


codecov[bot]: # [Codecov](https://codecov.io/gh/tefra/xsdata/pull/531?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou) Report
> Merging [#531](https://codecov.io/gh/tefra/xsdata/pull/531?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou) (0902351) into [master](https://codecov.io/gh/tefra/xsdata/commit/557126850f9bb560f4db9d8118bacd43b6300c7d?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou) (5571268) will **decrease** coverage by `0.09%`.
> The diff coverage is `33.33%`.

[![Impacted file tree graph](https://codecov.io/gh/tefra/xsdata/pull/531/graphs/tree.svg?width=650&height=150&src=pr&token=YzDDLtywvl&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou)](https://codecov.io/gh/tefra/xsdata/pull/531?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou)

```diff
@@             Coverage Diff             @@
##            master     #531      +/-   ##
===========================================
- Coverage   100.00%   99.90%   -0.10%     
===========================================
  Files           95       95              
  Lines         7662     7637      -25     
  Branches      1325     1326       +1     
===========================================
- Hits          7662     7630      -32     
- Misses           0        4       +4     
- Partials         0        3       +3     
```


| [Impacted Files](https://codecov.io/gh/tefra/xsdata/pull/531?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou) | Coverage Δ | |
|---|---|---|
| [xsdata/formats/dataclass/parsers/handlers/lxml.py](https://codecov.io/gh/tefra/xsdata/pull/531/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL2Zvcm1hdHMvZGF0YWNsYXNzL3BhcnNlcnMvaGFuZGxlcnMvbHhtbC5weQ==) | `94.73% <33.33%> (-5.27%)` | :arrow_down: |
| [xsdata/utils/hooks.py](https://codecov.io/gh/tefra/xsdata/pull/531/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL3V0aWxzL2hvb2tzLnB5) | `81.81% <0.00%> (-18.19%)` | :arrow_down: |
| [xsdata/formats/dataclass/typing.py](https://codecov.io/gh/tefra/xsdata/pull/531/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL2Zvcm1hdHMvZGF0YWNsYXNzL3R5cGluZy5weQ==) | `97.02% <0.00%> (-2.98%)` | :arrow_down: |
| [xsdata/cli.py](https://codecov.io/gh/tefra/xsdata/pull/531/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL2NsaS5weQ==) | `100.00% <0.00%> (ø)` | |
| [xsdata/models/xsd.py](https://codecov.io/gh/tefra/xsdata/pull/531/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL21vZGVscy94c2QucHk=) | `100.00% <0.00%> (ø)` | |
| [xsdata/models/wsdl.py](https://codecov.io/gh/tefra/xsdata/pull/531/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL21vZGVscy93c2RsLnB5) | `100.00% <0.00%> (ø)` | |
| [xsdata/models/config.py](https://codecov.io/gh/tefra/xsdata/pull/531/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL21vZGVscy9jb25maWcucHk=) | `100.00% <0.00%> (ø)` | |
| [xsdata/models/mixins.py](https://codecov.io/gh/tefra/xsdata/pull/531/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL21vZGVscy9taXhpbnMucHk=) | `100.00% <0.00%> (ø)` | |
| [xsdata/utils/testing.py](https://codecov.io/gh/tefra/xsdata/pull/531/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL3V0aWxzL3Rlc3RpbmcucHk=) | `100.00% <0.00%> (ø)` | |
| [xsdata/codegen/mixins.py](https://codecov.io/gh/tefra/xsdata/pull/531/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL2NvZGVnZW4vbWl4aW5zLnB5) | `100.00% <0.00%> (ø)` | |
| ... and [5 more](https://codecov.io/gh/tefra/xsdata/pull/531/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/tefra/xsdata/pull/531?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/tefra/xsdata/pull/531?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou). Last update [5571268...0902351](https://codecov.io/gh/tefra/xsdata/pull/531?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou).

sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=BUG)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=VULNERABILITY)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=531&resolved=false&types=SECURITY_HOTSPOT) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=531&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=531&resolved=false&types=SECURITY_HOTSPOT)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=531&resolved=false&types=CODE_SMELL)

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo.png' alt='No Coverage information' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=531) No Coverage information  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='0.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=531&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=531&metric=new_duplicated_lines_density&view=list)


tefra: For now this is an lxml only feature I am afraid.

Patch:
diff --git a/docs/_static/config.sample.xml b/docs/_static/config.sample.xml
index 556d3d7d..dc9fca73 100644
--- a/docs/_static/config.sample.xml
+++ b/docs/_static/config.sample.xml
@@ -2,7 +2,7 @@
 <Config xmlns="http://pypi.org/project/xsdata" version="21.6">
   <Output maxLineLength="79">
     <Package>generated</Package>
-    <Format>dataclasses</Format>
+    <Format relativeImports="false">dataclasses</Format>
     <Structure>filenames</Structure>
     <DocstringStyle>reStructuredText</DocstringStyle>
     <CompoundFields>false</CompoundFields>
diff --git a/docs/json.rst b/docs/json.rst
index 3185c83e..53b09314 100644
--- a/docs/json.rst
+++ b/docs/json.rst
@@ -30,12 +30,8 @@ context instance.
     from tests.fixtures.books.books import Books
 
 
-Parsing JSON
-============
-
-
-From json filename
-------------------
+Parse from json filename
+========================
 
 .. doctest::
 
@@ -52,8 +48,8 @@ From json filename
     BookForm(author='Hightower, Kim', title='The First Book', genre='Fiction', price=44.95, pub_date=XmlDate(2000, 10, 1), review='An amazing story of nothing.', id='bk001', lang='en')
 
 
-From json file object
----------------------
+Parse from json file object
+===========================
 
 .. doctest::
 
@@ -64,8 +60,8 @@ From json file object
     BookForm(author='Hightower, Kim', title='The First Book', genre='Fiction', price=44.95, pub_date=XmlDate(2000, 10, 1), review='An amazing story of nothing.', id='bk001', lang='en')
 
 
-From json stream
-----------------
+Parse from json stream
+======================
 
 .. doctest::
 
@@ -75,8 +71,8 @@ From json stream
     BookForm(author='Hightower, Kim', title='The First Book', genre='Fiction', price=44.95, pub_date=XmlDate(2000, 10, 1), review='An amazing story of nothing.', id='bk001', lang='en')
 
 
-From json string
-----------------
+Parse from json string
+======================
 
 .. doctest::
 
@@ -85,8 +81,8 @@ From json string
     BookForm(author='Hightower, Kim', title='The First Book', genre='Fiction', price=44.95, pub_date=XmlDate(2000, 10, 1), review='An amazing story of nothing.', id='bk001', lang='en')
 
 
-From json bytes
----------------
+Parse from json bytes
+=====================
 
 .. doctest::
 
@@ -95,8 +91,8 @@ From json bytes
     BookForm(author='Hightower, Kim', title='The First Book', genre='Fiction', price=44.95, pub_date=XmlDate(2000, 10, 1), review='An amazing story of nothing.', id='bk001', lang='en')
 
 
-From json path
---------------
+Parse from json Path
+====================
 
 .. doctest::
 
@@ -105,8 +101,12 @@ From json path
     BookForm(author='Hightower, Kim', title='The First Book', genre='Fiction', price=44.95, pub_date=XmlDate(2000, 10, 1), review='An amazing story of nothing.', id='bk001', lang='en')
 
 
-Ignore unknown properties
--------------------------
+Parse json with unknown properties
+==================================
+
+By default the parser will fail on unknown properties, but you can disable these
+errors through configuration.
+
 
 .. doctest::
 
@@ -127,8 +127,8 @@ Ignore unknown properties
 API :ref:`Reference <ParserConfig>`.
 
 
-Unknown json target type
-------------------------
+Parse with unknown json target type
+===================================
 
 It's optimal to provide the target model but completely optional. The parser can scan
 all the imported modules to find a matching dataclass.
@@ -156,8 +156,8 @@ all the imported modules to find a matching dataclass.
     if the configuration option is disabled!
 
 
-List of Objects
----------------
+Parser list of objects
+======================
 
 Specify the target binding type to ``List[ModelName]``
 
@@ -191,8 +191,8 @@ Specify the target binding type to ``List[ModelName]``
     'Nagata, Suanne'
 
 
-Custom json load factory
-------------------------
+Parser with custom json load factory
+====================================
 
 The default factory is python's builtin :func:`python:json.load` but you can use any
 other implementation as long as it's has a compatible signature.
@@ -204,12 +204,8 @@ other implementation as long as it's has a compatible signature.
     parser = JsonParser(load_factory=ujson.load)
 
 
-Serializing JSON
-================
-
-
-Render json string
-------------------
+Serialize json to string
+========================
 
 .. doctest::
 
@@ -264,9 +260,8 @@ Render json string
     }
 
 
-
-Write to json stream
---------------------
+Serialize json to stream
+=========================
 
 .. doctest::
 
@@ -304,8 +299,8 @@ Write to json stream
     >>> path.unlink()
 
 
-Custom Dict factory
--------------------
+Serialize with custom dict factory
+==================================
 
 By using a custom dict factory you can change the output behaviour, like filter out
 ``None`` values.
@@ -341,8 +336,8 @@ or conveniently
     {"author": "Nagata, Suanne", "title": "Becoming Somebody", "price": 33.95, "pub_date": "2001-01-10", "review": "A masterpiece of the fine art of gossiping.", "id": "bk002", "lang": "en"}
 
 
-Custom json dump factory
-------------------------
+Serialize with custom json dump factory
+=======================================
 
 The default factory is python's builtin :func:`python:json.dump` but you can use any
 other implementation as long as it's has a compatible signature.
diff --git a/docs/xml.rst b/docs/xml.rst
index 55d571d4..69ea3630 100644
--- a/docs/xml.rst
+++ b/docs/xml.rst
@@ -30,11 +30,8 @@ context instance.
     from tests.fixtures.primer import PurchaseOrder, Usaddress
 
 
-Parsing XML
-===========
-
-From xml filename
-------------------
+Parse from xml filename
+=======================
 
 .. doctest::
 
@@ -50,8 +47,8 @@ From xml filename
     Usaddress(name='Robert Smith', street='8 Oak Avenue', city='Old Town', state='PA', zip=Decimal('95819'), country='US')
 
 
-From xml file object
---------------------
+Parse from xml file object
+==========================
 
 .. doctest::
 
@@ -62,8 +59,8 @@ From xml file object
     '8 Oak Avenue'
 
 
-From xml stream
----------------
+Parse from xml stream
+=====================
 
 .. doctest::
 
@@ -73,8 +70,8 @@ From xml stream
     '8 Oak Avenue'
 
 
-From xml string
----------------
+Parse from xml string
+=====================
 
 .. doctest::
 
@@ -83,8 +80,8 @@ From xml string
     '8 Oak Avenue'
 
 
-From xml bytes
---------------
+Parse from xml bytes
+====================
 
 .. doctest::
 
@@ -93,8 +90,8 @@ From xml bytes
     '8 Oak Avenue'
 
 
-From xml path
--------------
+Parse from xml Path
+===================
 
 .. doctest::
 
@@ -103,8 +100,27 @@ From xml path
     '8 Oak Avenue'
 
 
-Unknown xml target type
------------------------
+Parse from lxml Element or Tree
+===============================
+
+The :class:`~xsdata.formats.dataclass.parsers.handlers.LxmlEventHandler`, which is
+the default one when lxml is installed, can also be used to bind data directly
+from an Element or Tree.
+
+.. doctest::
+
+    >>> import lxml
+    >>> from xsdata.formats.dataclass.parsers.handlers import LxmlEventHandler
+    ...
+    >>> parser = XmlParser(handler=LxmlEventHandler)
+    >>> tree = lxml.etree.parse(str(xml_path))
+    >>> bill_to = parser.parse(tree.find('.//billTo'), Usaddress)
+    >>> bill_to
+    Usaddress(name='Robert Smith', street='8 Oak Avenue', city='Old Town', state='PA', zip=Decimal('95819'), country='US')
+
+
+Parse with unknown xml target type
+==================================
 
 It's optimal to provide the target model but completely optional. The parser can scan
 all the imported modules to find a matching dataclass.
@@ -115,7 +131,10 @@ all the imported modules to find a matching dataclass.
 
 
 Parser Config
--------------
+=============
+
+The configuration allows to enable/disable various features and failures.
+
 
     >>> from xsdata.formats.dataclass.parsers.config import ParserConfig
     ...
@@ -132,8 +151,8 @@ Parser Config
 API :ref:`Reference <ParserConfig>`.
 
 
-Alternative handlers
---------------------
+Parse xml with alternative handlers
+===================================
 
 XmlHandlers read the xml source and push build events to create the target class.
 xsData ships with multiple handlers based on lxml and native python that vary in
@@ -163,12 +182,8 @@ performance and features.
 Read :ref:`more... <XML Handlers>`
 
 
-Serializing XML
-===============
-
-
-Render xml string
------------------
+Serialize xml to string
+=======================
 
 .. doctest::
 
@@ -207,8 +222,8 @@ Render xml string
     <BLANKLINE>
 
 
-Set custom prefixes
---------------------
+Serialize xml with custom namespace prefixes
+============================================
 
 .. doctest::
 
@@ -227,8 +242,8 @@ Set custom prefixes
     <BLANKLINE>
 
 
-Set a default namespace
------------------------
+Serialize xml with default namespace
+====================================
 
 .. doctest::
 
@@ -247,8 +262,8 @@ Set a default namespace
     <BLANKLINE>
 
 
-Write to xml stream
--------------------
+Serialize xml to stream
+=======================
 
 .. doctest::
 
@@ -274,23 +289,27 @@ Write to xml stream
     >>> path.unlink()
 
 
-Serializer Config
------------------
+Serialize xml with alternative writers
+======================================
+
+xsData ships with multiple writers based on lxml and native python that may vary
+in performance in some cases. The output of all them is consistent with a few
+exceptions when handling mixed content with ``pretty_print=True``.
+
+.. hint::
+
+    If you installed xsdata with lxml the default writer is set to
+    :class:`~xsdata.formats.dataclass.serializers.writers.LxmlEventWriter` otherwise
+    :class:`~xsdata.formats.dataclass.serializers.writers.XmlEventWriter` will be used.
 
 .. doctest::
 
-    >>> from xsdata.formats.dataclass.serializers.config import SerializerConfig
+    >>> from xsdata.formats.dataclass.serializers.writers import XmlEventWriter
     ...
-    >>> serializer = XmlSerializer(config=SerializerConfig(
-    ...     pretty_print=True,
-    ...     encoding="UTF-8",
-    ...     xml_version="1.1",
-    ...     xml_declaration=False,
-    ...     schema_location="urn books.xsd",
-    ...     no_namespace_schema_location=None,
-    ... ))
+    >>> serializer = XmlSerializer(config=config, writer=XmlEventWriter)
     >>> print(serializer.render(books))
-    <ns0:books xmlns:ns0="urn:books" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn books.xsd">
+    <?xml version="1.0" encoding="UTF-8"?>
+    <ns0:books xmlns:ns0="urn:books">
       <book id="bk001" lang="en">
         <author>Hightower, Kim</author>
         <title>The First Book</title>
@@ -302,31 +321,26 @@ Serializer Config
     </ns0:books>
     <BLANKLINE>
 
+Read :ref:`more... <XML Writers>`
 
-Read :ref:`more... <SerializerConfig>`
-
-
-Alternative Writers
--------------------
-
-xsData ships with multiple writers based on lxml and native python that may vary
-in performance in some cases. The output of all them is consistent with a few
-exceptions when handling mixed content with ``pretty_print=True``.
-
-.. hint::
 
-    If you installed xsdata with lxml the default writer is set to
-    :class:`~xsdata.formats.dataclass.serializers.writers.LxmlEventWriter` otherwise
-    :class:`~xsdata.formats.dataclass.serializers.writers.XmlEventWriter` will be used.
+Serializer Config
+=================
 
 .. doctest::
 
-    >>> from xsdata.formats.dataclass.serializers.writers import XmlEventWriter
+    >>> from xsdata.formats.dataclass.serializers.config import SerializerConfig
     ...
-    >>> serializer = XmlSerializer(config=config, writer=XmlEventWriter)
+    >>> serializer = XmlSerializer(config=SerializerConfig(
+    ...     pretty_print=True,
+    ...     encoding="UTF-8",
+    ...     xml_version="1.1",
+    ...     xml_declaration=False,
+    ...     schema_location="urn books.xsd",
+    ...     no_namespace_schema_location=None,
+    ... ))
     >>> print(serializer.render(books))
-    <?xml version="1.0" encoding="UTF-8"?>
-    <ns0:books xmlns:ns0="urn:books">
+    <ns0:books xmlns:ns0="urn:books" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn books.xsd">
       <book id="bk001" lang="en">
         <author>Hightower, Kim</author>
         <title>The First Book</title>
@@ -338,4 +352,5 @@ exceptions when handling mixed content with ``pretty_print=True``.
     </ns0:books>
     <BLANKLINE>
 
-Read :ref:`more... <XML Writers>`
+
+Read :ref:`more... <SerializerConfig>`
diff --git a/xsdata/formats/dataclass/parsers/handlers/lxml.py b/xsdata/formats/dataclass/parsers/handlers/lxml.py
index b6dca20f..6cd4b835 100644
--- a/xsdata/formats/dataclass/parsers/handlers/lxml.py
+++ b/xsdata/formats/dataclass/parsers/handlers/lxml.py
@@ -23,13 +23,22 @@ class LxmlEventHandler(XmlHandler):
 
     def parse(self, source: Any) -> Any:
         """
-        Parse an XML document from a system identifier or an InputSource.
+        Parse an XML document from a system identifier or an InputSource or
+        directly from an lxml Element or Tree.
+
+        When Source is an lxml Element or Tree the handler will switch
+        to the :class:`lxml.etree.iterwalk` api.
+
+        When source is a system identifier or an InputSource the parser
+        will ignore comments and recover from errors.
 
-        The xml parser will ignore comments, recover from errors. The
-        parser will parse the whole document and then walk down the tree
-        if the process xinclude is enabled.
+        When config process_xinclude is enabled the handler will parse
+        the whole document and then walk down the element tree.
         """
-        if self.parser.config.process_xinclude:
+
+        if isinstance(source, (etree._ElementTree, etree._Element)):
+            ctx = etree.iterwalk(source, EVENTS)
+        elif self.parser.config.process_xinclude:
             tree = etree.parse(source, base_url=self.parser.config.base_url)  # nosec
             tree.xinclude()
             ctx = etree.iterwalk(tree, EVENTS)


Test patch:
diff --git a/tests/formats/dataclass/parsers/handlers/test_lxml.py b/tests/formats/dataclass/parsers/handlers/test_lxml.py
index deebfd58..390ad70a 100644
--- a/tests/formats/dataclass/parsers/handlers/test_lxml.py
+++ b/tests/formats/dataclass/parsers/handlers/test_lxml.py
@@ -1,7 +1,10 @@
 from unittest import mock
 from unittest.case import TestCase
 
+from lxml import etree
+
 from tests import fixtures_dir
+from tests.fixtures.books import BookForm
 from tests.fixtures.books import Books
 from tests.fixtures.books.fixtures import books
 from tests.fixtures.books.fixtures import events
@@ -28,6 +31,17 @@ class LxmlEventHandlerTests(TestCase):
         self.assertEqual({None: "urn:books"}, self.parser.ns_map)
         self.assertEqual(events_default_ns, self.parser.events)
 
+    def test_parse_with_element_or_tree(self):
+        path = fixtures_dir.joinpath("books/books.xml")
+        tree = etree.parse(str(path))
+
+        result = self.parser.parse(tree, Books)
+        self.assertEqual(books, result)
+
+        tree = etree.parse(str(path))
+        result = self.parser.parse(tree.find(".//book"), BookForm)
+        self.assertEqual(books.book[0], result)
+
     def test_parse_with_xinclude(self):
         path = fixtures_dir.joinpath("books/books-xinclude.xml")
         ns_map = {"brk": "urn:books", "xi": "http://www.w3.org/2001/XInclude"}