XML Merge Algorithm
Magento merges XML files from multiple modules into a single configuration.
Merge rules:
- Same elements with same attributes → merged
- Same elements with different attributes → merged
- New elements → appended
- Element order preserved per module
Example:
<!-- Module A: etc/di.xml -->
<type name="ClassName">
<arguments>
<argument name="param1" xsi:type="string">value1</argument>
</arguments>
</type>
<!-- Module B: etc/di.xml -->
<type name="ClassName">
<arguments>
<argument name="param2" xsi:type="string">value2</argument>
</arguments>
</type>
<!-- Merged result -->
<type name="ClassName">
<arguments>
<argument name="param1" xsi:type="string">value1</argument>
<argument name="param2" xsi:type="string">value2</argument>
</arguments>
</type>
Override behavior:
<!-- Module A: etc/config.xml -->
<default>
<vendor_module>
<general>
<title>Default Title</title>
</general>
</vendor_module>
</default>
<!-- Module B: etc/config.xml -->
<default>
<vendor_module>
<general>
<title>Override Title</title>
</general>
</vendor_module>
</default>
<!-- Result: Module B wins (later in load order) -->
<vendor_module>
<general>
<title>Override Title</title>
</general>
</vendor_module>
Merge Order
XML files are merged in a specific order based on module dependencies.
Global XML merge order:
1. Magento framework XML
2. Magento modules (sorted by sequence dependencies)
3. Third-party modules
4. Your module (last wins)
Area-specific merge order:
1. etc/*.xml (global)
2. etc/{area}/*.xml (area-specific)
3. Area-specific takes precedence
Example — di.xml merge order:
1. vendor/magento/framework/etc/di.xml
2. vendor/magento/module-catalog/etc/di.xml
3. vendor/magento/module-customer/etc/di.xml
4. app/code/Vendor/Module/etc/di.xml
5. app/code/Vendor/Module/etc/frontend/di.xml (if frontend area)
Module load order:
# Check module load order
php bin/magento module:status --dependencies
# This determines XML merge order
Key principle:
- Later modules override earlier modules for same keys
- Area-specific overrides global
- Last module in sequence wins
Area-Specific Overrides
Area-specific XML files override global configuration.
Override example:
<!-- etc/di.xml (global) -->
<type name="Vendor\Module\Service\Logger">
<arguments>
<argument name="logLevel" xsi:type="string">info</argument>
</arguments>
</type>
<!-- etc/frontend/di.xml (frontend only) -->
<type name="Vendor\Module\Service\Logger">
<arguments>
<argument name="logLevel" xsi:type="string">warning</argument>
</arguments>
</type>
<!-- etc/adminhtml/di.xml (admin only) -->
<type name="Vendor\Module\Service\Logger">
<arguments>
<argument name="logLevel" xsi:type="string">debug</argument>
</arguments>
</type>
Result by area:
Frontend: logLevel = warning (area override)
Admin: logLevel = debug (area override)
Cron: logLevel = info (global default)
REST API: logLevel = info (global default)
Available areas for XML:
etc/ → Global (all areas)
etc/frontend/ → Frontend only
etc/adminhtml/ → Admin only
etc/crontab/ → Cron only
etc/webapi_rest/ → REST API only
etc/webapi_graphql/ → GraphQL only
Events.xml area override:
<!-- etc/events.xml: Observer active everywhere -->
<event name="catalog_product_save_after">
<observer name="vendor_product_sync" instance="...\ProductSync"/>
</event>
<!-- etc/frontend/events.xml: Additional frontend observer -->
<event name="catalog_product_save_after">
<observer name="vendor_product_frontend" instance="...\ProductFrontend"/>
</event>
<!-- Result: Both observers execute on frontend -->
<!-- Only ProductSync executes in admin/cron -->
Debugging Merge Conflicts
Tools and techniques for debugging XML configuration issues.
Debugging di.xml:
# Check compiled configuration
cat var/di/etc/module.xml
# See all type configurations
php bin/magento setup:di:compile 2>&1 | grep -i error
# Check virtual types
grep -r "virtualType" app/code/Vendor/Module/etc/di.xml
Debugging system.xml:
# Check config values
php bin/magento config:show vendor_module/
# Clear config cache
php bin/magento cache:clean config
# Check database
mysql -u root -p magento -e "SELECT * FROM core_config_data WHERE path LIKE 'vendor%';"
Common merge issues:
1. Duplicate keys → Last value wins (may not be what you expect)
2. Missing parent elements → Child not merged
3. Wrong area → Config not loaded
4. Cache not cleared → Old config persists
Debugging tools:
# Clear all caches
php bin/magento cache:flush
# Check XML validity
xmllint --noout app/code/Vendor/Module/etc/di.xml
# View merged config
cat var/di/etc/module.xml | head -50
# Check module load order
php bin/magento module:status --dependencies
XML validation:
// Check XML syntax
$doc = new DOMDocument();
$doc->loadXML($xmlString);
if (!$doc->validate()) {
echo "XML is invalid\n";
}
Force recompilation:
# After XML changes
cache:flush
setup:di:compile
setup:static-content:deploy -f
Quiz
1. When two modules define the same config key, which wins?
2. What takes precedence: global or area-specific di.xml?
3. How do you debug merged XML configuration?
4. What determines the XML merge order between modules?
Flashcards
Question
What is the core XML merge rule?
Click to reveal answer
Answer
Later modules override earlier modules for same keys
Question
Which takes precedence: global or area-specific?
Click to reveal answer
Answer
Area-specific overrides global
Question
Where is compiled DI config stored?
Click to reveal answer
Answer
var/di/etc/
Question
How do you clear config cache?
Click to reveal answer
Answer
php bin/magento cache:clean config
Question
What determines module load order?
Click to reveal answer
Answer
Sequence dependencies in module.xml
Revision Notes
Key Takeaways
- 1. Magento merges XML from multiple modules into single configuration
- 2. Later modules override earlier modules for duplicate keys
- 3. Area-specific XML overrides global XML
- 4. Module sequence dependencies determine merge order
- 5. Use CLI commands and var/di/ for debugging
- 6. Always clear cache after XML changes
Interview Tips
- • Explain the XML merge algorithm
- • Describe how area-specific overrides work
- • Know how to debug merge conflicts
- • Discuss module load order and its impact
Cheat Sheet
XML Merging Cheat Sheet
Merge rules:
- Same keys: last module wins
- Different keys: appended
- Area-specific > global
- Module sequence determines order
Debug tools:
- var/di/etc/ — Compiled config
- cache:flush — Clear cache
- module:status --dependencies — Load order
- config:show — View values
Area directories:
- etc/ (global)
- etc/frontend/
- etc/adminhtml/
- etc/crontab/
- etc/webapi_rest/
- etc/webapi_graphql/
After XML changes:
- cache:flush
- setup:di:compile
- setup:static-content:deploy