Обнаружение пустого узла XML с помощью PHP SimpleXML

Позвольте мне начать с того, что я не очень разбираюсь в разборе XML и / или написании PHP. Я изучал и собирал вещи вместе для того, над чем я работаю, но я застрял.

Я пытаюсь создать базовый оператор if / else: если узел не пустой, напишите содержимое узла.

Вот фрагмент XML-кода, который я называю:

<channel>
<item>
<title>This is a test</title>
<link />
<description>Test description</description>
<category>Test category</category>
<guid />
</item>
</channel>

а вот и PHP, который у меня пока есть:

<?php
$alerts = simplexml_load_file('example.xml');
$guid = $alerts->channel->item->guid;

if ($guid->count() == 0) {
print "// No alert";
}
else {
echo "<div class='emergency-alert'>".$guid."</div>";
}

?>

Очевидно, «guid» — это пустой узел, но он возвращает:

<div class="emergency-alert"> </div>

Что я делаю неправильно? 🙁

PS, я пробовал hasChildren (), и это тоже не сработало.

2

Решение

@ Wrikken прав. XPath является предпочтительным способом запроса документов XML. Но, отвечая на ваш вопрос, в вашем простом случае вы можете проверить, является ли значение узла пустым, приведя SimpleXMLElement к строке:

if ( !$guid->__toString() ) {
print "No alert";
}
3

Другие решения

foreach($alerts->xpath("//item/guid[normalize-space(.)!='']") as $guid){
echo "<div class='emergency-alert'>".$guid."</div>";
}

Что оно делает?

  1. xpath: простой способ запроса XML-документов
  2. normalize-space: строка аргумента с удаленными начальными, конечными и повторяющимися пробелами (т.е. <guid> </guid> это не пустая строка, это ' ', но этот превращает его в ''
  3. . это текстовое содержимое узла
2

В PHP SimpleXMLElement который представляет пустой элемент XML (самозакрывающийся тег или пустую пару тегов открытия / закрытия без содержимого), преобразуется в логическое значение FALSE, Это, возможно, немного неожиданно, так как обычно каждый объект в PHP приводится к логическому TRUE:

var_dump((bool) new SimpleXMLElement("<guid/>")); # bool(false)

var_dump((bool) new SimpleXMLElement("<guid></guid>")); # bool(false)

var_dump((bool) new SimpleXMLElement("<guid> </guid>")); # bool(true)

Это специальное правило задокументировано в руководстве по PHP на Преобразование в логическое значение.

Вы можете использовать это, чтобы проверить, действительно ли <guid> элемент у вас есть пустой. Однако, здесь важно, вы спрашиваете об элементе конкретно. В вашем существующем коде:

$guid = $alerts->channel->item->guid;

вы не просите конкретный <guid> элемент, но для всех, которые являются потомками родителя <item> элемент. Эти виды SimpleXMLElement объекты приводятся к логическому значению true, если они не содержат нулевых элементов (сравните с вашим использованием SimpleXMLElement::count()).

Отличается от этого, если вы получите первый <guid> элемент за индексом, вы получите SimpleXMLElement этого индекса или же NULL в случае, если элемент не существует (это означает, что нет <guid> элемент).

Оба — несуществующий элемент как NULL или существующий, пустой — приведёт к логическому false который может быть легко использован в вашем операторе if / else:

$guid = $alerts->channel->item->guid[0];
### zero is the index of the first element
if ((bool) $guid) {
# non-empty, existing <guid> element
} else {
# empty or non-existing
}

Это тогда отвечает на ваш вопрос.

0
По вопросам рекламы [email protected]