xmapper helps you inspect, compare, and transform XML feeds without hand-writing XSLT or ad-hoc scripts. It normalises XML into stable dot-path/value mappings, lets you bootstrap YAML mapping rules from sample documents, and provides helpers to read, modify, and regenerate XML.
- Flatten XML into predictable dot-paths such as
listing.ad.listingId. - Read, update, and diff XML payloads programmatically.
- Auto-generate YAML mapping templates from example source/target documents.
- Rebuild well-formatted XML strings or files after applying your mappings.
- Works on small one-off transformations or large batch pipelines.
pip install xmapperEditable install for development:
pip install -e .The library supports Python 3.8 through 3.12. Runtime dependencies: lxml>=4.9,<5, PyYAML>=6.0, and untangle==1.2.1.
from xmapper import parse
from xmapper.utils import dump_str
source_xml = """<?xml version='1.0' encoding='UTF-8'?>
<listing>
<ad>
<type>house</type>
<listingId>353324</listingId>
<priority>high</priority>
<url>https://img.599245196.jpg</url>
</ad>
</listing>
"""
obj = parse(source_xml)
print(sorted(obj.paths))
# ['listing.ad.listingId', 'listing.ad.priority', 'listing.ad.type', 'listing.ad.url']
print(obj.get_value_by_path('listing.ad.priority'))
# 'high'
obj.set_value_by_path('listing.ad.priority', 'low')
print(dump_str(obj))Output:
<?xml version='1.0' encoding='UTF-8'?>
<listing>
<ad>
<type>house</type>
<listingId>353324</listingId>
<priority>low</priority>
<url>https://img.599245196.jpg</url>
</ad>
</listing>Use the Mapper to discover how fields line up between two XML structures. This example uses raw XML strings, but file paths work as well.
from xmapper import Mapper
source_xml = """<?xml version='1.0' encoding='UTF-8'?>
<listing>
<ad>
<type>house</type>
<listingId>353324</listingId>
<priority>high</priority>
<url>https://img.599245196.jpg</url>
</ad>
</listing>
"""
target_xml = """<?xml version='1.0' encoding='UTF-8'?>
<property>
<id>353324</id>
<type>house</type>
<propertyType>house</propertyType>
<salePriority>high</salePriority>
<image>https://img.599245196.jpg</image>
</property>
"""
mapper = Mapper(source_xml, target_xml)
mapper.build_mapping()
print(mapper.MAPPER['exact_match'])
# {'property.id': 'listing.ad.listingId',
# 'property.image': 'listing.ad.url',
# 'property.propertyType': 'listing.ad.type',
# 'property.salePriority': 'listing.ad.priority',
# 'property.type': 'listing.ad.type'}Mapper.build_mapping() prints three buckets:
exact_match– fields with a single match in the source.multiple_match– fields with more than one possible source path.human_intervention– fields that need manual mapping.
Persist the suggestion to YAML for later review:
mapper.dump_yaml_config('mapping.yaml')When you want to verify that two payloads carry the same data (regardless of element order), use Comparer.
from xmapper import Comparer
comparer = Comparer('feed_a.xml', 'feed_b.xml')
if comparer.compare():
print('Feeds match')
else:
print('Differences found')The comparer walks every path/value pair and prints any mismatches, so you can focus on the problematic fields instead of raw diffs.
- Onboard a new partner feed by generating mapping templates from sample XML.
- Build regression checks to ensure your exports still conform to downstream schemas.
- Transform legacy XML dumps into a normalised structure before loading into databases.
- Audit vendor feeds for missing or misplaced values.
python -m unittest discover testsMIT