Проблема кодирования вывода XML/XSLT с использованием php XSLTProcessor

Я экспортирую набор записей в xml, а затем в xliff посредством преобразования xslt. Экспорт работает нормально, но мне не удается преобразовать некоторые символы в экспортный файл. Вот здесь некоторые пошаговые детали:

Шаг 1. Пользователь вводит смешанную строку символов, например. следующая строка Autocomplete On' see the wrong character ==> í

Кодировка поля Mysql db/table установлена ​​​​на utf8, например

  `unicode longtext COLLATE utf8_unicode_ci`

который хранит приведенный выше текст.

Шаг 2. Фрагмент html создается для целей экспорта, например

<html version="1.2">
    <table>
        <tr>
            <td id="Autocomplete_On">Autocomplete On' see the wrong character ==&#62; í</td>
        </tr>
    </table>
    </html>

Шаг 3. Преобразование в xml

  <?xml version="1.0" standalone="yes"?>
     <html version="1.2"><body><table><tr><td id="Autocomplete_On">
        Autocomplete On' see the wrong character ==&gt; &#xC3;&#xAD;</td>
</tr></table></body></html>

Шаг 4: Преобразуйте с помощью xslt:

(вставил только желаемую часть вывода, при просмотре в браузере я вижу это, а фактический символ в файле Ã)

 <body>
      <group id="id796986axmarkhtml-0">
        <group id="id533787bxmarkbody-1">
          <group id="id533788bxmarktable-2">
            <group id="id533790bxmarktr-3">
              <trans-unit id="td-4">
                <source>Autocomplete On' see the wrong character ==&gt; í</source>
                <target>Autocomplete On' see the wrong character ==&gt; í</target>
              </trans-unit>
            </group>
          </group>
        </group>
      </group>
    </body>

Фактический код:

  private function xml2xliff($htmlStr,$source,$target){
        $xml=new \DOMDocument();
        //hacky way to tidy html
        @$xml->loadHTML($htmlStr);//step 3
        $xsl = new \DOMDocument;
        $xsl->load(__DIR__.'/xliff/xsl/xml2xliff.xsl');
        $proc = new \XSLTProcessor();
        $proc->ImportStyleSheet($xsl);
        $proc->setParameter('', 'source', $this->getIsoName($source));
        $proc->setParameter('', 'target', $this->getIsoName($target));
        return $proc->transformToXML($xml); //step 4
    }

$htmlStr — фрагмент html, сгенерированный на шаге 2,

Итак, проблема в том, что строка дважды преобразуется. Фактический рассматриваемый персонаж

шаг 1. í

шаг 2. еще í

шаг 3. конвертируется в Ã т.е. &#xC3;&#xAD;

шаг 4. преобразовано в í

Другой пример:

вход. Autocomplete On They’re gone now

вывод xml. Autocomplete On Theyâre gone now


person sakhunzai    schedule 16.05.2014    source источник


Ответы (1)


DOMDocument::loadHtml() загружает ваш html как ANSI, но это UTF-8. Таким образом, специальный символ разделяется и уничтожается. Вы можете обмануть его, используя UTF-8 с инструкцией обработки XML:

$html = <<<HTML
<html>
  <table>
    <tr>
      <td id="Autocomplete_On">Autocomplete On' see the wrong character ==&#62; í</td>
    </tr>
  </table>
</html>
HTML;

$dom = new DOMDocument('1.0', 'UTF-8');

$dom->loadHTML('<?xml encoding="UTF-8"?>'.$html);
var_dump(
  $dom->saveXml()
);

Выход:

string(331) "<?xml version="1.0" standalone="yes"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<?xml encoding="UTF-8"??>
<html version="1.2"><body><table><tr><td id="Autocomplete_On">Autocomplete On' see the wrong character ==&gt; &#xED;</td>&#xD;
    </tr></table></body></html>
"
person ThW    schedule 17.05.2014
comment
спасибо, что устранили проблему, мне интересно, что произойдет с символами в другой кодировке, например, с апострофом, например, в Autocomplete On They’re gone now . - person sakhunzai; 19.05.2014
comment
зачем добавлять <?xml encoding="UTF-8"??> см. ?? двойные вопросительные знаки - person sakhunzai; 19.05.2014