Skip to content
intermediate Phase 32 · Advanced XML

How Magento Merges XML

Merge order, area-specific overrides, debugging merge conflicts, and XML configuration resolution.

45m
0 problems
Topic Progress 0%

XML Merge Algorithm

Magento merges XML files from multiple modules into a single configuration.

Merge rules:

  1. Same elements with same attributes → merged
  2. Same elements with different attributes → merged
  3. New elements → appended
  4. 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?

Question 1 options

2. What takes precedence: global or area-specific di.xml?

Question 2 options

3. How do you debug merged XML configuration?

Question 3 options

4. What determines the XML merge order between modules?

Question 4 options

Flashcards

Question

What is the core XML merge rule?

Answer

Later modules override earlier modules for same keys

Question

Which takes precedence: global or area-specific?

Answer

Area-specific overrides global

Question

Where is compiled DI config stored?

Answer

var/di/etc/

Question

How do you clear config cache?

Answer

php bin/magento cache:clean config

Question

What determines module load order?

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:

  1. Same keys: last module wins
  2. Different keys: appended
  3. Area-specific > global
  4. 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:

  1. cache:flush
  2. setup:di:compile
  3. setup:static-content:deploy