Замедляет ли дополнительное пространство процессор?

Узнав как "правильно" отключить узел, я заметил, что использование функции PHP unset() оставляет табуляции и пробелы позади. Так что теперь у меня есть этот большой кусок белого пространства между узлами время от времени. Мне интересно, перебирает ли PHP пробелы/возвраты/вкладки и будет ли это в конечном итоге замедлять работу системы.

Я также спрашиваю, можно ли легко удалить неустановленное пространство?

Спасибо, Райан

ДОБАВЛЕНИЕ ПРИМЕЧАНИЕ:

Вот как я удалил пробелы после удаления узла, и это сработало для меня.

$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->load($xmlPath);
$dom->save($xmlPath);

person NightHawk    schedule 15.09.2010    source источник


Ответы (4)


Может ли это замедлить процесс: вероятно, слишком мало забот.

А simpleXML — это просто. Если вам нужен «красивый» вывод, DOM — ваш друг:

<?php
$xml = '
<xml>
        <node>foo </node>
        <other>bar</other>
</xml>';
$x = new SimpleXMLElement($xml);
unset($x->other);
echo $x->asXML();

$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($xml);
$dom->documentElement->removeChild($dom->documentElement->lastChild);
echo $dom->saveXML();
person Wrikken    schedule 15.09.2010
comment
Заменено правильно на красиво, чтобы избежать недопонимания о правильности беспорядочного XML-документа. - person Josh Davis; 16.09.2010
comment
Это эквивалент unset? $dom-›documentElement-›removeChild($dom-›documentElement-›lastChild); Могу ли я опустить эту строку, если я просто хочу отформатировать вывод? Спасибо, Райан - person NightHawk; 16.09.2010
comment
Да, эта строка предназначена только для случайных манипуляций с DOM и может быть легко опущена. Если вы хотите отформатировать вывод SimpleXML, нередко просто import результат помещается в DOM и вызывается saveXML для красивого форматирования. - person Wrikken; 16.09.2010
comment
Я получил эту ошибку при попытке использовать вышеупомянутый подход: Предупреждение: DOMDocument::loadXML() [domdocument.loadxml]: ожидается начальный тег, '‹' не найден в Entity, строка: 1 В моем исследовании я нашел это bugs.php.net/bug.php?id=45996, но у меня 2.7. 6, поэтому я не уверен, что это все еще применимо. - person NightHawk; 16.09.2010
comment
Я не зря сказал import ;). Попробуйте использовать эту функцию здесь: php.net/manual/en /function.dom-import-simplexml.php Если это не сработает, опубликуйте / вставьте код, который вы пытаетесь использовать. - person Wrikken; 16.09.2010
comment
ХОРОШО :). Вот что я сделал, теперь у меня нет ошибок, но в документе все еще есть пробелы: $dom = dom_import_simplexml($xml)-›ownerDocument; $dom-›preserveWhiteSpace = false; $dom-›formatOutput = true; $dom-›saveXML(); - person NightHawk; 16.09.2010
comment
Вы должны установить preserveWhiteSpace в false и formatOutput в true до загрузки в него XML. - person Wrikken; 20.09.2010
comment
Хорошо, заработало. См. рабочий код наверху. Это правильный способ сделать это? Спасибо, Райан - person NightHawk; 20.09.2010

Пробелы в XML — это TextNodes, например.

<foo>
    <bar>baz</bar>
</foo>

действительно

<foo><- whitespace node
    -><bar>baz</bar><- whitespace node
-></foo>

Если вы удалите узел <bar>, вы получите

<foo><- whitespace node
    -><- whitespace node
-></foo>

Я думаю, что SimpleXml не позволит вам легко получить доступ к узлам Text (возможно, через XPath), но DOM позволяет. Подробности см. в ответе Wrikken. Теперь, когда вы знаете, что пробел — это узел, вы также можете представить, что его разбор в узел занимает несколько циклов процессора. Тем не менее, я бы сказал, что влияние скорости незначительно. Если вы сомневаетесь, сделайте тест с некоторыми реальными данными.


EDIT: Доказательство того, что пробелы на самом деле являются узлами

$xml = <<< XML
<foo>
    <bar>baz</bar>
</foo>
XML;

$dom = new DOMDocument;
$dom->loadXML($xml);
foreach($dom->documentElement->childNodes as $node) {
    var_dump($node);
}

дает

object(DOMText)#4 (0) {}
object(DOMElement)#6 (0) {}
object(DOMText)#4 (0) {}
person Gordon    schedule 15.09.2010
comment
Вы не подразумеваете, что пробел - это тег?! ;-) Кроме того, Libxml может отличать пробельные узлы от текста, на самом деле XMLReader имеет 2 типа пробельных символов. - person Robin; 16.09.2010
comment
XPath, конечно, будет //text()[normalize-space()=''], но они будут удалены при загрузке, если для preserveWhiteSpace установлено значение false. - person Wrikken; 16.09.2010
comment
@Robin: Я думаю, Гордон имел в виду, что это настоящие узлы. - person Wrikken; 16.09.2010
comment
@Robin <whitespace> не должен был подразумевать тег, а просто означал, что между тегами есть узел. Извините, если это ввело в заблуждение. Изменил его на, надеюсь, менее двусмысленный маркер. - person Gordon; 16.09.2010

На самом деле это Libxml, который выполняет синтаксический анализ XML, пробелы считываются синтаксическим анализатором так же, как и любой другой символ во входном потоке. (или файл). Большинство PHP xml API используют Libxml под капотом (XmlReader, XmlWriter, SimpleXml Xslt, Dom...) - некоторые из них дают вам доступ к пробелам (например, Dom, XmlReader), некоторые нет (например, SimpleXML)

person Robin    schedule 15.09.2010

Быстрые ответы на заданные вопросы:

Мне интересно, перебирает ли PHP пробелы/возвраты/вкладки и будет ли это в конечном итоге замедлять работу системы.

Нет, PHP (или libxml) на самом деле не перебирает его. Наличие большего количества пробелов теоретически замедляет работу системы, хотя оно настолько мало, что его нельзя измерить напрямую. Вы можете проверить это самостоятельно, удалив все пробелы из вашего XML. Это не сделало бы это быстрее.

Я также спрашиваю, можно ли легко удалить неустановленное пространство?

Боюсь, это не легкий способ. Вы можете импортировать свои материалы SimpleXML в DOM и использовать formatOutput для полной реконструкции пробелов, как это предлагается в другом ответе, или вы можете использовать стороннюю библиотеку, которая сделает это за вас, но вы не найдете простой встроенный способ сделать это.

person Josh Davis    schedule 16.09.2010