How to easily Debug Layout Xml Warning/Error?

2019-02-01 19:20发布

I got stuck on this error:

Warning: simplexml_load_string(): Entity: line 46: parser error : Comment not terminated  in */lib/Varien/Simplexml/Config.php on line 510

and

Entity: line 46: parser error : Start tag expected, '<' not found  in */lib/Varien/Simplexml/Config.php on line 510

It is clear that there is an issue in some Xml file, but really not easy for me to find out the needle in the big haystack :)

Any good practice for that? If possible I would like to find a good practice that involves use Xdebug, or some log.

It happens a lot of time in Magento to do some miss spelling.

6条回答
Explosion°爆炸
2楼-- · 2019-02-01 19:45

Edit file app/code/core/Mage/Core/Model/Layout/Update.php and search for function "getFileLayoutUpdatesXml".

Add:

Mage::log(print_r($filename, true));

aproximately at line 442, before:

$fileStr = file_get_contents($filename);
查看更多
smile是对你的礼貌
3楼-- · 2019-02-01 19:47

Well, after a good search, if the $string is all the CML merged, you have almost not chance to find what tag is bad closed.

I found a way to do it, in the class /lib/Varien/Simplexml/Config.php you have to modify the next method:

public function loadFile($filePath)
{
    if (!is_readable($filePath)) {
        //throw new Exception('Can not read xml file '.$filePath);
        return false;
    }

    $fileData = file_get_contents($filePath);
    $fileData = $this->processFileData($fileData);
    //add this try catch
    try{
        $this->loadString($fileData, $this->_elementClass);
    } catch (Exception $e) {
        var_dump("The error: " . $e->getMessage());
        var_dump("The bad file" . $filePath);
    }

    return $this->loadString($fileData, $this->_elementClass);
}

In this way we now can see what file has a bad tag.

查看更多
The star\"
4楼-- · 2019-02-01 19:56

in

*/lib/Varien/Simplexml/Config.php on line 510

go and add a debug line and echo out the xml it tries to load and see what is wrong with this string.

查看更多
在下西门庆
5楼-- · 2019-02-01 20:05

If your test environment is Linux, you can also use XMLLint xmllint to check the layout xml file for inconsistencies after you've made changes to it. Checking before implementation discovers a multitude of sins and prevents having errors thrown.

查看更多
一纸荒年 Trace。
6楼-- · 2019-02-01 20:11

I think you can take a look at this article Dealing with XML errors.

This warning is related to some config.xml error, so a possible workaround to find out the exact file is to mod. the /lib/Varien/Simplexml/Config.php class.

You should modify Varien_Simplexml_Config::loadString() method:

public function loadString($string)
{
    if (is_string($string)) {
        // Enable internal errors
        libxml_use_internal_errors(true);
        $xml = simplexml_load_string($string, $this->_elementClass);
        if (false === $xml) {
            // Put breakpoint here
            $errors = libxml_get_errors();
        }
        if ($xml instanceof Varien_Simplexml_Element) {
            $this->_xml = $xml;
            return true;
        }
    } else {
        Mage::logException(new Exception('"$string" parameter for simplexml_load_string is not a string'));
    }
    return false;
}

In case the error is related to some Layout file ( Update.php line 444 warning )

You should modify Mage_Core_Model_Layout_Update::getFileLayoutUpdatesXml() method in a similar way:

public function getFileLayoutUpdatesXml($area, $package, $theme, $storeId = null)
{
    if (null === $storeId) {
        $storeId = Mage::app()->getStore()->getId();
    }
    /* @var $design Mage_Core_Model_Design_Package */
    $design = Mage::getSingleton('core/design_package');
    $layoutXml = null;
    $elementClass = $this->getElementClass();
    $updatesRoot = Mage::app()->getConfig()->getNode($area.'/layout/updates');
    Mage::dispatchEvent('core_layout_update_updates_get_after', array('updates' => $updatesRoot));
    $updateFiles = array();
    foreach ($updatesRoot->children() as $updateNode) {
        if ($updateNode->file) {
            $module = $updateNode->getAttribute('module');
            if ($module && Mage::getStoreConfigFlag('advanced/modules_disable_output/' . $module, $storeId)) {
                continue;
            }
            $updateFiles[] = (string)$updateNode->file;
        }
    }
    // custom local layout updates file - load always last
    $updateFiles[] = 'local.xml';
    $layoutStr = '';
    foreach ($updateFiles as $file) {
        $filename = $design->getLayoutFilename($file, array(
            '_area'    => $area,
            '_package' => $package,
            '_theme'   => $theme
        ));
        if (!is_readable($filename)) {
            continue;
        }
        $fileStr = file_get_contents($filename);
        $fileStr = str_replace($this->_subst['from'], $this->_subst['to'], $fileStr);   


        libxml_use_internal_errors(true);
        $fileXml = simplexml_load_string($fileStr, $elementClass);


        if (false === $fileXml) {
            // Put breakpoint here
            $errors = libxml_get_errors();
            $err = array($filename, $errors);
            // error detail and file name will be printed
            Zend_Debug::dump($err);
            die();
        }



        if (!$fileXml instanceof SimpleXMLElement) {
            continue;
        }
        $layoutStr .= $fileXml->innerXml();
    }
    $layoutXml = simplexml_load_string('<layouts>'.$layoutStr.'</layouts>', $elementClass);
    return $layoutXml;
}

Now just reload the page a read the error info.

查看更多
Luminary・发光体
7楼-- · 2019-02-01 20:12

To resolve that case, in same file */lib/Varien/Simplexml/Config.php on line#489

Print path of loaded XML file put Zend_Debug::dump($filePath); after $fileData = $this->processFileData($fileData);

and overwrite function loadString($string)


if (is_string($string)) {
    $xml = simplexml_load_string($string, $this->_elementClass);
    if ($xml instanceof Varien_Simplexml_Element) {
        $this->_xml = $xml;
        return true;
    }
} else {
    Mage::logException(new Exception('"$string" parameter for simplexml_load_string is not a string'));
}
return false;

Replace with

if (is_string($string)) {
    // Enable internal errors
    //Mage::log($string);
    libxml_use_internal_errors(true);
    $xml = simplexml_load_string($string, $this->_elementClass);

    if (false === $xml) {
        // Put breakpoint here
        $errors = libxml_get_errors();
        $err = array($errors);
        // error detail and file name will be printed
        Zend_Debug::dump($string);;
        Zend_Debug::dump($err);
        die();
    }
    if ($xml instanceof Varien_Simplexml_Element) {
        $this->_xml = $xml;
        return true;
    }
} else {
    Mage::logException(new Exception('"$string" parameter for simplexml_load_string is not a string'));
}
return false;

And this will print the path and error where this create problem.

查看更多
登录 后发表回答