Позвольте мне начать с того, что я не очень разбираюсь в разборе 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 (), и это тоже не сработало.
@ Wrikken прав. XPath является предпочтительным способом запроса документов XML. Но, отвечая на ваш вопрос, в вашем простом случае вы можете проверить, является ли значение узла пустым, приведя SimpleXMLElement к строке:
if ( !$guid->__toString() ) {
print "No alert";
}
foreach($alerts->xpath("//item/guid[normalize-space(.)!='']") as $guid){
echo "<div class='emergency-alert'>".$guid."</div>";
}
Что оно делает?
<guid> </guid>
это не пустая строка, это ' '
, но этот превращает его в ''
.
это текстовое содержимое узлаВ 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
}
Это тогда отвечает на ваш вопрос.