webew
Войти » Регистрация
 
PHP

Экранирование PHP_EOL в xml-аттрибуте

15 октября 2015, 2:20
Автор: deadka
Доброго времени суток!

Есть нужда "ручками" собрать xml, не используя специализированные средства как DOMDocument.

Проблема в том, что PHP_EOL, который находится в аттрибуте сохраняется по разному - DomDocument::SaveXML преобразует его в 
,
а htmlspecialchars этого не делает. Возникает вопрос - какой специализированной функцией (или набором) можно вместо (или в дополнение к) htmlcpecialchars добиться нужного результата без говнокодных замен уровня

$val = str_replace(PHP_EOL,"
",$val);

.

Прошу поделиться соображениями.
Код (текущий вариант создаёт два идентичных файла, но боюсь, что какие-то символы не учел и изобретаю велосипед):

   $dom = new DOMDocument('1.0', 'UTF-8');
    $root = $dom->createElement('root');
    $dom->appendChild($root);
    $point_node = $dom->createElement('marker');
    $point_node = $root->appendChild($point_node);

    $val = "a".PHP_EOL."b";

    $point_node->setAttribute('id',$val);
    $_1 = $dom->saveXML();
    file_put_contents("1",$_1);

    $val = htmlspecialchars($val,ENT_QUOTES,'UTF-8');

    $val = str_replace(PHP_EOL,"
",$val);

    $_2 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>".PHP_EOL."<root><marker id=\"". $val  . "\"/></root>".PHP_EOL;
    file_put_contents("2",$_2);
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
NO USERPIC

rgbeast

Если не использовать спецсредства, например http://php.net/xmlwriter , то потребуется некоторая ручная работа. Нужно смотреть внимательно спецификацию XML и тестировать итоговый XML. С какой целью собирать XML руками?
15.10.2015, 10:45
Ответить

deadka

Спасибо, посмотрю xmlwriter.
Очень узкое место - оптимизируем всеми способами, ручная сборка даёт выигрыш по времени, как показали замеры времени (по сравнению с использованием DomDocument). По ajax-запросу на сервере собирается большая xml и передаётся на клиент. json получается еще больше размером, из-за русских символов.
Через more, через less мы бредем в страну чудес...
15.10.2015, 13:16
Ответить
NO USERPIC

rgbeast

В случае ручной сборки, вероятно, нужно делать так, как у Вас написано. И сделать тест, в котором будут все символы, которые в принципе могут участвовать в значении атрибута
15.10.2015, 14:17
Ответить

deadka

Перебрав весь набор ascii символов, выявил вот такое преобразование, которое приведено в функции ниже.
Такое значение xml-аттрибута, подействовав на которое моя функция даёт другой результат, чем DomDocument->saveXML найти не смог. Если кто найдет - пишите обязательно )).

function likexml($val) {
  $val = htmlspecialchars($val,ENT_COMPAT,'UTF-8');
  $val = str_replace(PHP_EOL,"&#10;",$val);
  $val = str_replace(chr(13),"&#13;",$val);
  $val = str_replace("\t","&#9;",$val);
  return $val;
}
Через more, через less мы бредем в страну чудес...
16.10.2015, 02:37
Ответить

1234ru

Если стоит задача
deadka
нужда "ручками" собрать xml
то замены уровня $val = str_replace(PHP_EOL,"&#10;",$val) я бы к говнокодным относить не стал :)

Если гонитесь за скоростью - попробуйте объединить вызовы str_replace() в один:
$val = str_replace(
    [ PHP_EOL, chr(13), "\t"],
    [ '&#10;', '&#13', '&#9'],
    $val
);

То, что не убивает нас, делает нас инвалидами.
16.10.2015, 14:06
Ответить
NO USERPIC

rgbeast

Поддерживаю Михаила. Также, называл бы символы единообразно
chr(10), chr(13), chr(9)
или
"\n", "\r", "\t"

Использования PHP_EOL я бы избегал категорически. Нам нужен именно 10 символ, а что является новой строкой для PHP может в принципе зависеть от настроек PHP, версии PHP, кодировки.
16.10.2015, 14:20
Ответить

deadka

Цитата:

Использования PHP_EOL я бы избегал категорически. Нам нужен именно 10 символ, а что является новой строкой для PHP может в принципе зависеть от настроек PHP, версии PHP, кодировки.

А также от операционки. Да, в точку.. Видимо лучше "\n", "\r", "\t", чтобы функцию chr не вызывать ). Осталось только в кроссплатформенности убедиться ).
Через more, через less мы бредем в страну чудес...
16.10.2015, 15:06
Ответить

deadka

Цитата:
то замены уровня $val = str_replace(PHP_EOL,"&#10;",$val) я бы к говнокодным относить не стал :)

Если нету никакой встроенной в php функции, которая сделает именно это, то да. Плохо выразился, стоило "велосипедный" написать ). Спасибо за рекомендацию. Секунду времени я выиграл, к слову, на всем этом велосипеде )).
Через more, через less мы бредем в страну чудес...
16.10.2015, 15:03
Ответить

1234ru

Цитата:
Секунду времени я выиграл

А всего секунд сколько? :)
То, что не убивает нас, делает нас инвалидами.
17.10.2015, 09:01
Ответить

1234ru

Покажи вообще весь кусок ради интереса - может, еще секунду-другую выжмем
То, что не убивает нас, делает нас инвалидами.
17.10.2015, 09:07
Ответить

deadka

Всего 3 секунды, а стало 2. Так что не зря война прошла!
Весь кусок кода - большой, так спамить не хочется ). Идея в том, что выборка из БД суется в XML, а он отдаётся на клиент, выжимать больше особо нечего. Хорошую оптимизацию дал <IfModule mod_deflate.c> ))
Через more, через less мы бредем в страну чудес...
17.10.2015, 12:04
Ответить

1234ru

Так сжатие ведь на скорость построения XML не влияет. От него уменьшается только время передачи на клиент, это оно было 3 секунды?
То, что не убивает нас, делает нас инвалидами.
17.10.2015, 18:57
Ответить

deadka

Сжатие конечно не в контексте xml - а в общем смысле было сказано. сэкономило тотальное время - то есть от отправления запроса на сервер и до получения ответа.
Через more, через less мы бредем в страну чудес...
17.10.2015, 19:02
Ответить
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
© 2008—2017 webew.ru, связаться: x собака webew.ru
Сайт использует Flede и соответствует стандартам WAI-WCAG 1.0 на уровне A.
Rambler's Top100