Другая ошибка синтаксического анализа PHP XML: «Введен неверный код UTF-8, укажите кодировку!» - PullRequest
3 голосов
/ 11 января 2011

Ошибка:

Предупреждение: simplexml_load_string () [function.simplexml-load-string]: Entity: строка 3: ошибка синтаксического анализатора: неверный ввод UTF-8, указать кодировку!Байты: 0xE7 0x61 0x69 0x73

XML из базы данных (вывод из источника представления в FF):

<?xml version="1.0" encoding="UTF-8" ?><audit><audit_detail>
    <fieldname>role_fra</fieldname>
    <old_value>Role en fran&#xe7;ais</old_value>
    <new_value>Role &#xe7; en fran&#xe7;ais</new_value>
</audit_detail></audit></xml>

Если я правильно понимаю, ошибка связана с первым закодированным çв теге old_value.Чтобы быть точным, ошибка связана с этим на основе байтов: «çais»?

Вот как я загружаю XML:

$xmlData = simplexml_load_string($ed['updates'][$i]['audit_data']);

Цикл I, используя это:

foreach ($xmlData->audit_detail as $a){
//code here
}

Поле в базе данных имеет тип данных text и установлено utf8_general_ci.

Моя функция для создания заглушек audit_detail:

function ed_audit_node($field, $new, $old){


    $old = htmlentities($old, ENT_QUOTES, "UTF-8");
    $new = htmlentities($new, ENT_QUOTES, "UTF-8");

    $out = <<<EOF
        <audit_detail>
            <fieldname>{$field}</fieldname>
            <old_value>{$old}</old_value>
            <new_value>{$new}</new_value>
        </audit_detail>
EOF;
    return $out;
}

Вставка в базу данныхвыполняется следующим образом:

function ed_audit_insert($ed, $xml){
    global $visitor;

    $sql = <<<EOF
    INSERT INTO ed.audit
    (employee_id, audit_date, audit_action, audit_data, user_id) 
    VALUES (
        {$ed[emp][employee_id]}, 
        now(), 
        '{$ed[audit_action]}', 
        '{$xml}', 
        {$visitor[user_id]}
    );      
EOF;
    $req = mysql_query($sql,$ed['db']) or die(db_query_error($sql,mysql_error(),__FUNCTION__));

}

Самое странное состоит в том, что в простом файле PHP работает (без объявления xml) следующее:

$testxml = <<<EOF
<audit><audit_detail>
        <fieldname>role_fra</fieldname>
        <old_value>Role en fran&#xe7;ais</old_value>
        <new_value>Role &#xe7; en fran&#xe7;ais</new_value>
    </audit_detail></audit>
EOF;

$ xmlData = simplexml_load_string ($testxml);

Может ли кто-нибудь помочь пролить свет на это?

Edit # 1 - Я сейчас использую DOM для создания XML-документа и избавился отОшибка.Функция здесь:

$dom = new DomDocument();
$root = $dom->appendChild($dom->createElement('audit'));
$xmlCount = 0;

if($role_fra != $curr['role']['role_fra']){
   $root->appendChild(ed_audit_node($dom, 'role_fra', $role_fra, $curr['role']['role_fra'])); 
   $xmlCount++;
}

...

function ed_audit_node($dom, $field, $new, $old){

    //create audit_detail node
    $ad = $dom->createElement('audit_detail');

    $fn = $dom->createElement('fieldname');
    $fn->appendChild($dom->createTextNode($field));
    $ad->appendChild($fn);

    $ov = $dom->createElement('old_value');
    $ov->appendChild($dom->createTextNode($old));
    $ad->appendChild($ov);

    $nv = $dom->createElement('new_value');
    $nv->appendChild($dom->createTextNode($new));
    $ad->appendChild($nv);

    //append to document
    return $ad;
}

if($xmlCount != 0){
    ed_audit_insert($ed,$dom->saveXML());   
}

Однако, я думаю, что теперь у меня есть проблема с отображением, поскольку этот текст "Roééleç sé en franêais" (новое_значение) отображается как:

проблема с отображением: image

In my HTML document, I have the following declaration for content-type (unfortunately, I don't hold the keys to make changes here):

 ...

Я пробовал iconv () для преобразования в ISO-8859-1, однако большинство специальных символов удаляются при выполнении преобразования.Осталось только «Ro» с помощью этой команды:

iconv('UTF-8','ISO-8859-1',$node->new_value);

iconv output:

Поле в БД: utf8_general_ci.Тем не менее, кодировка соединения будет любой по умолчанию.

Не совсем уверен, куда идти отсюда ...

Edit # 2 - Я попытался utf8_decode, чтобы увидетьесли это не поможет, но это не поможет.

utf8_decode($a->new_value);

Вывод:

Я также заметил, что мое поле в БД содержало UTF-8.Что хорошо.

1 Ответ

3 голосов
/ 11 января 2011

Когда &#xe7; равно "ç", тогда ваша кодировка - Windows-1252 (или, возможно, ISO-8859-1), но не UTF-8.

...