如何使用 PHP 检查 XML 标签是否为空?
How to check if XML tag is empty using PHP?
如果我的 XML 文件的内容是:
<query>
<results/>
</query>
我正在使用 $obj = simplexml_load_file( $filepath )
所以文件内容存储在 $obj
.
如您所见,结果标签是空的,没有文本或属性。
如何检查结果标签是否为空?
我考虑过这样做 if ( empty( $obj->results ) )
但我认为那不是正确的语法。
As you can see, the results tag is empty, it has no text or attributes.
How can I check if the results tag is empty?
在 XML 中,一个元素被认为是 empty by definition 如果:
[Definition: An element with no content is said to be empty.] The representation of an empty element is either a start-tag immediately followed by an end-tag, or an empty-element tag. [Definition: An empty-element tag takes a special form:] [... it follows the definition of the empty-element tag with "/>" at then end]
所以无论是<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);
此示例只是将 $buffer
中的小 XML 文档与 SimpleXML 解析为 $xml
。然后第一个和第二个 results
元素通过 SimpleXML 的 DOM 姊妹库检查 children 的数量。如果children的个数为零,则元素为空。
$isEmpty = !dom_import_simplexml($element)->childNodes->length;
使用“纯”SimpleXML 你会遇到问题,因为 simple 中的 simple 模型有限Simple XML 此处提供。例如,SimpleXML 不考虑注释,如果注释不是 leaf-nodes,则访问 text-nodes 时会出现问题。您可以(但不能像我在 DOM 中展示的那样)使用 xpath 查询解决 SimpleXML 中的一些限制。例如,如果元素 not 为空,则只匹配该元素,因此再次计数为 0 表示一个空元素:
var_dump(count($element->xpath('(.)[./node()]')));
这里的xpath
(.)[./node()]
表示:如果当前元素有child-nodes,则只获取当前元素。因此,如果不为空则查询 returns 一个元素,如果为空则查询零个元素。这是在 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
*/
$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());
如果我的 XML 文件的内容是:
<query>
<results/>
</query>
我正在使用 $obj = simplexml_load_file( $filepath )
所以文件内容存储在 $obj
.
如您所见,结果标签是空的,没有文本或属性。
如何检查结果标签是否为空?
我考虑过这样做 if ( empty( $obj->results ) )
但我认为那不是正确的语法。
As you can see, the results tag is empty, it has no text or attributes.
How can I check if the results tag is empty?
在 XML 中,一个元素被认为是 empty by definition 如果:
[Definition: An element with no content is said to be empty.] The representation of an empty element is either a start-tag immediately followed by an end-tag, or an empty-element tag. [Definition: An empty-element tag takes a special form:] [... it follows the definition of the empty-element tag with "/>" at then end]
所以无论是<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);
此示例只是将 $buffer
中的小 XML 文档与 SimpleXML 解析为 $xml
。然后第一个和第二个 results
元素通过 SimpleXML 的 DOM 姊妹库检查 children 的数量。如果children的个数为零,则元素为空。
$isEmpty = !dom_import_simplexml($element)->childNodes->length;
使用“纯”SimpleXML 你会遇到问题,因为 simple 中的 simple 模型有限Simple XML 此处提供。例如,SimpleXML 不考虑注释,如果注释不是 leaf-nodes,则访问 text-nodes 时会出现问题。您可以(但不能像我在 DOM 中展示的那样)使用 xpath 查询解决 SimpleXML 中的一些限制。例如,如果元素 not 为空,则只匹配该元素,因此再次计数为 0 表示一个空元素:
var_dump(count($element->xpath('(.)[./node()]')));
这里的xpath
(.)[./node()]
表示:如果当前元素有child-nodes,则只获取当前元素。因此,如果不为空则查询 returns 一个元素,如果为空则查询零个元素。这是在 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
*/
$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());