检查孩子是否存在? - SimpleXML(PHP)

时间:2017-02-24 11:38:43

标签: php xml simplexml

我有不同的XML文件,我为每个XML文件重命名所有单独的标记,以便每个XML文件具有相同的标记名称。这很简单,因为该函数是为XML文件定制的。

但是现在为每个XML文件编写7个新函数的instand我想检查XML文件是否有特定的孩子。因为如果我想说:

foreach ($items as $item) {
$node = dom_import_simplexml($item);
$title = $node->getElementsByTagName('title')->item(0)->textContent;
$price = $node->getElementsByTagName('price')->item(0)->textContent;
$url = $node->getElementsByTagName('url')->item(0)->textContent;
$publisher = $node->getElementsByTagName('publisher')->item(0)->textContent;
$category = $node->getElementsByTagName('category')->item(0)->textContent;
$platform = $node->getElementsByTagName('platform')->item(0)->textContent;
}

我有时会得到:PHP Notice: Trying to get property of non-object in ...

例如。两个不同的XML表。一个包含发布者,类别和平台,另一个不包含:

XML 1:

<products>
  <product>
    <desc>This is a Test</desc>
    <price>11.69</price>
    <price_base>12.99</price_base>
    <publisher>Stackoverflow</publisher>
    <category>PHP</category>
    </packshot>
    <title>Check if child exists? - SimpleXML (PHP)</title>
    <url>http://stackoverflow.com/questions/ask</url>
  </product>
</products>

XML 2:

<products>
  <product>
   <image></image>
    <title>Questions</title>
    <price>23,90</price>
    <url>google.de/url>
    <platform>Stackoverflow</platform>
  </product>
</products>

您看,有时一个XML文件包含发布者,类别和平台,但有时不包含。 但也可能是因为并非XML文件的每个节点都包含所有属性,例如第一个!

因此,如果节点包含发布者,类别或/和平台,我需要检查XML文件的每个节点。

如何使用SimpleXML实现这一目标? 我考虑过switch case,但首先我需要检查每个节点中包含哪些子节点。

修改 也许我找到了解决方案。这是一个解决方案吗?

if($node->getElementsByTagName('platform')->item(0)){
        echo $node->getElementsByTagName('platform')->item(0)->textContent . "\n";
    }

问候,谢谢!

2 个答案:

答案 0 :(得分:0)

罗马的一种方式......(工作示例)

$xml = "<products>
  <product>
    <desc>This is a Test</desc>
    <price>11.69</price>
    <price_base>12.99</price_base>
    <publisher>Stackoverflow</publisher>
    <category>PHP</category>
    <title>Check if child exists? - SimpleXML (PHP)</title>
    <url>http://stackoverflow.com/questions/ask</url>
  </product>
</products>";
$xml = simplexml_load_string($xml);
#set fields to look for
foreach(['desc','title','price','publisher','category','platform','image','whatever'] as $path){
       #get the first node
       $result = $xml->xpath("product/{$path}[1]");
       #validate and set
       $coll[$path] = $result?(string)$result[0]:null;  
       #if you need here a local variable do (2 x $)
       ${$path} = $coll[$path];
}
#here i do array_filter() to remove all NULL entries
print_r(array_filter($coll));
#if local variables needed do
extract($coll);#this creates $desc, $price

注意</packshot>是一个无效的节点,在此处删除。

xpath语法https://www.w3schools.com/xmL/xpath_syntax.asp

答案 1 :(得分:0)

首先,通过使用dom_import_simplexml从SimpleXML切换到DOM,您的代码过于复杂。使用SimpleXML可以在更短的代码中完成使用DOM的操作。

而不是:

$node = dom_import_simplexml($item);
$title = $node->getElementsByTagName('title')->item(0)->textContent;

你可以使用:

$title = (string)$item->title[0];

甚至只是:

$title = (string)$item->title;

要了解其工作原理,请查看the SimpleXML examples in the manual

有了这些知识,你会惊讶于看孩子是否存在是多么简单:

if ( isset($item->title) ) {
    $title = (string)$item->title;
} else {
    echo "There is no title!";
}