Специальный символ в XML с помощью PHP

Я пытаюсь создать XML-файл с некоторыми значениями, которые содержат специальные символы, такие как μmol / l, x10³ cells / μl и многие другие. также нужна функциональность для добавления в верхние индексы.

Я закодировал текст μmol / l на что-то вроде этого, используя функцию ordutf8 от php.net

& # 956 & # 109 & # 111 & # 108 & # 47 & # 108

function ords_to_unistr($ords, $encoding = 'UTF-8'){ // Turns an array of ordinal values into a string of unicode characters $str = ''; for($i = 0; $i < sizeof($ords); $i++){ // Pack this number into a 4-byte string // (Or multiple one-byte strings, depending on context.) $v = $ords[$i]; $str .= pack("N",$v); } $str = mb_convert_encoding($str,$encoding,"UCS-4BE"); return($str); } function unistr_to_ords($str, $encoding = 'UTF-8'){ // Turns a string of unicode characters into an array of ordinal values, // Even if some of those characters are multibyte. $str = mb_convert_encoding($str,"UCS-4BE",$encoding); $ords = array(); // Visit each unicode character for($i = 0; $i < mb_strlen($str,"UCS-4BE"); $i++){ // Now we have 4 bytes. Find their total // numeric value. $s2 = mb_substr($str,$i,1,"UCS-4BE"); $val = unpack("N",$s2); $ords[] = $val[1]; } return($ords); } 

Я успешно преобразовал этот код в «richtext» с помощью PHPExcel для создания документов Excel и PDF, но теперь мне нужно поместить его в XML.

Если я использую символы & #, так как я получаю сообщение об ошибке

SimpleXMLElement :: addChild (): недопустимое значение десятичного знака

Вот больше значений, которые у меня есть в базе данных, которые должны быть сделаны «XML» дружественными

& # 120 & # 49 & # 48 & # 60 & # 115 & # 117 & # 112 & # 62 & # 54 & # 60 & # 47 & # 115 & # 117 & # 112 & # 62 & # 32 & # 99 & # 101 & # 108 & # 108 & # 115 & # 47 & # 181 & # 108

Конвертировано из x10 3 клеток / мкл

Solutions Collecting From Web of "Специальный символ в XML с помощью PHP"

Здесь нет необходимости кодировать эти символы. Строки XML могут использовать UTF-8 или другую кодировку. В зависимости от кодировки сериализатор будет кодировать по мере необходимости.

 $foo = new SimpleXmlElement('<?xml version="1.0" encoding="UTF-8"?><foo/>'); $foo->addChild('bar', 'μmol/l, x10³ cells/µl'); echo $foo->asXml(); 

Выход (специальные символы, не закодированные):

 <?xml version="1.0" encoding="UTF-8"?> <foo><bar>μmol/l, x10³ cells/µl</bar></foo> 

Чтобы принудительно создавать сущности для специальных символов, вам необходимо изменить кодировку:

 $foo = new SimpleXmlElement('<?xml version="1.0" encoding="ASCII"?><foo/>'); $foo->addChild('bar', 'μmol/l, x10³ cells/µl'); echo $foo->asXml(); 

Выход (специальные символы закодированы):

 <?xml version="1.0" encoding="ASCII"?> <foo><bar>&#956;mol/l, x10&#179; cells/&#181;l</bar></foo> 

Я предлагаю вам преобразовать пользовательскую кодировку обратно в UTF-8. Таким образом, XML Api может позаботиться об этом. Если вам нравится хранить строку с пользовательской кодировкой, вам нужно обходить ошибку .

Строка типа &#120&#49&#48&#60&#115&#117 запускает ошибку в SimpleXML / DOM. Второй аргумент SimpleXMLElement::addChild() и DOMDocument::createElement() имеет сломанное экранирование. Вам нужно создать контент как текстовый узел и добавить его.

Вот небольшой класс, который расширяет SimpleXMLElement и добавляет обходной путь:

 class MySimpleXMLElement extends SimpleXMLElement { public function addChild($nodeName, $content = NULL) { $child = parent::addChild($nodeName); if (isset($content)) { $node = dom_import_simplexml($child); $node->appendChild($node->ownerDocument->createTextNode($content)); } return $child; } } $foo = new MySimpleXmlElement('<?xml version="1.0" encoding="UTF-8"?><foo/>'); $foo->addChild('bar', '&#120&#49&#48&#60&#115&#117'); echo $foo->asXml(); 

Вывод:

 <?xml version="1.0" encoding="UTF-8"?> <foo><bar>&amp;#120&amp;#49&amp;#48&amp;#60&amp;#115&amp;#117</bar></foo> 

& Из вашей пользовательской кодировки получают escape-код как объект &amp; – потому что это особый символ в XML. Парсер XML расшифрует его.

 $xml = <<<'XML' <?xml version="1.0" encoding="UTF-8"?> <foo><bar>&amp;#120&amp;#49&amp;#48&amp;#60&amp;#115&amp;#117</bar></foo> XML; $foo = new SimpleXMLElement($xml); var_dump((string)$foo->bar); 

Вывод:

 string(27) "&#120&#49&#48&#60&#115&#117"