2017-02-24 144 views
1

我有不同的XML文件,我爲每個XML文件重命名所有單獨的標記,以便每個XML文件具有相同的標記名稱。這很簡單,因爲該功能是爲XML文件定製的。檢查孩子是否存在? - SimpleXML(PHP)

但是爲每個XML文件編寫7個新函數的例子現在我想檢查一個XML文件是否有specidifed子節點。因爲如果我想說:

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做到這一點? 我考慮過開關盒,但起初我需要檢查每個節點中包含哪些孩子。

編輯: 也許我找到了解決方案。這是一個解決方案嗎?

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

問候和謝謝你!

+0

你可以做'如果(isset($節點 - >的getElementsByTagName('出版商:

武裝與知識,你會發現它是多麼簡單,看是否有孩子存在與否驚訝') - > item))'和'if(is_array($ node-> getElementsByTagName('publisher') - > item))'驗證 – JustOnUnderMillions

+0

但您應該直接使用'simplexml'。 – JustOnUnderMillions

+0

可能重複的[php的SimpleXML檢查,如果一個孩子存在](http://stackoverflow.com/questions/1560827/php-simplexml-check-if-a-child-exists) –

回答

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

+0

路徑應該是'$ xml-> xpath(「products/product/{$ path} [1]」);'。或者我錯了? – Jan

+0

@Jan它關於相對絕對。絕對是'/ a/b/c'相對是'b/c'或'c'都會在這裏找到相同的數據。只有當你有komplex xml,其中子節點通常是相同的,那麼你最好做絕對路徑而不是相對一次。 – JustOnUnderMillions

+0

看看這裏https://www.w3schools.com/xmL/xpath_syntax.asp – JustOnUnderMillions

0

首先,你從SimpleXML的切換到DOM與dom_import_simplexml代碼過於複雜。您使用DOM所做的事情可以使用SimpleXML以更短的代碼完成。

取而代之的是:

$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!"; 
}