如果我的XML文件的内容是:
<query>
<results/>
</query>
我正在使用$obj = simplexml_load_file( $filepath )
,因此请将文件内容存储在$obj
。
如您所见,结果标记为空,没有文本或属性。
如何检查结果标记是否为空?
我考虑过这样做if ( empty( $obj->results ) )
,但我认为这不是正确的语法。
答案 0 :(得分:5)
如您所见,结果标记为空,没有文本或属性。
如何检查结果标记是否为空?
在XML中,如果符合以下内容,则会将元素视为empty by definition
[定义:没有content的元素被称为为空。]空元素的表示形式是一个开始标记,后面紧跟一个结束标记,或者一个空元素标签。 [定义:空元素标签采用特殊形式:] [...它遵循空元素标签的定义,使用&#34; /&gt;&#34;在那时结束]
无论是<results/>
还是<results></results>
,在XML中称为空元素。请注意<results foo="bar"/>
也是一个空元素。重要的是此处元素的内容,而不是属性。
现在在SimpleXML中,如何判断元素是否没有内容?它实际上非常麻烦。我更倾向于依靠DOM姐妹图书馆,然后它很直接:
<?php
$buffer = <<<XML
<query>
<results/>
<results></results>
</query>
XML;
$xml = simplexml_load_string($buffer);
$element = $xml->results[0];
var_dump(dom_import_simplexml($element)->childNodes->length);
$element = $xml->results[1];
var_dump(dom_import_simplexml($element)->childNodes->length);
此示例仅使用SimpleXML将$buffer
中的小XML文档解析为$xml
。然后通过SimpleXML的DOM姐妹库检查第一个和第二个 results
元素的子数。如果子元素数为零,则元素为空。
$isEmpty = !dom_import_simplexml($element)->childNodes->length;
&#34; pure&#34; SimpleXML您遇到了问题,因为此处提供的 Simple XML中的 simple 模型有限。例如,SimpleXML没有考虑注释,如果它们不是叶节点,则访问文本节点时会遇到问题。您可以(但不能像我在DOM中所示)使用xpath查询解决SimpleXML中的一些限制。例如,只有当元素不为空时才匹配元素,所以再次计数为0表示空元素:
var_dump(count($element->xpath('(.)[./node()]')));
这里的xpath
(.)[./node()]
表示:如果当前元素具有子节点,则仅获取它。因此,如果不为空,则查询返回一个元素,如果为空则返回零元这是在SimpleXML中检查空元素的一种方法。您可以扩展此原则以检查属性:
(.)[./node()|./@*]
也许有点神秘。但要回答你的问题,那就是要走的路:
$isEmpty = !count($element->xpath('(.)[./node()|./@*]'));
即:具有零属性的空XML元素。
希望这会有所帮助,并为您目前尚未探索过的领域提供一些启示。
以下是我在编写答案(try it online as well)时创建的一些示例代码沙箱样式:
<?php
/**
* How to check if XML tag is empty using PHP?
* @link http://stackoverflow.com/a/29614074/367456
*/
$buffer = <<<XML
<query>
<results/>
<results afri="cloa<a"/>
<results><!-- help --></results>
<results><!-- help -->1<test>222</test></results>
</query>
XML;
$xml = simplexml_load_string($buffer);
$element = $xml->results[0];
// $path = '*';
// $path = '.';
// $path = 'self::*';
// $path = 'self::*[1]';
// $path = 'descendant::node()';
// $path = 'self::*[descendant::node()]';
// $path = '(.)[descendant::node()]';
// $path = '(.)[.//node()]';
// $path = '(.)[child::node()]';
$path = '(.)[./node()]';
$result = $element->xpath($path);
var_dump(count($result));
foreach ($result as $node) {
echo $node->asXML(), "\n";
}
echo "------\n";
var_dump(count($element->xpath('(.)[./node()]')));
var_dump(count($element->xpath('(.)[./node()|./@*]')));
var_dump(strlen($element) + $element->children()->count());
$element = $xml->results[1];
var_dump(dom_import_simplexml($element)->childNodes->length);
$dom = dom_import_simplexml($element);
$dom->appendChild($dom->ownerDocument->createTextNode(""));
var_dump($element->children()->count());