2011-06-21 63 views
1

我解析XML文件時出現問題(編碼完好)。解析XML文件

考慮這樣的XML文件:

<?xml version="1.0" encoding="utf-8" ?> 
<root> 
    <list> 
     <item no="1"> 
      <title>Item's 1 title</title> 
      <content>Some long content with <special>tags</special> inside</content> 
     </item> 
     <item no="2"> 
      <title>Item's 2 title</title> 
      <content>Some long content with <special>tags</special> inside</content> 
     </item> 
    </list> 
</root> 

我需要在列表中每個項目的內容,內容並把它們放在一個陣列。一般來說不是問題,但是在這種情況下,我無法把頭轉向它。

問題出現在<content>內容中。它是中間有標籤的字符串。我無法找到提取內容的方法。 SimpleXML只返回/回顯包含<special>標籤的任何內容的字符串。就像這樣:

Some long content with inside. 

我非常想讓它變得像這樣的字符串:

Some long content with <special>tags</special> inside 

如何獲得呢?

+1

可能重複[PHP的SimpleXML獲得innerXML] (http://stackoverflow.com/questions/1937056/php-simplexml-get-innerxml) – Gordon

+0

我不認爲你應該混合文本節點與其他節點。理想情況下,您的XML應該像'<![CDATA [標籤裏面一些長的內容]]'它指示解析器不解析CDATA標記內的內容(原樣返回) – mkilmanas

+0

@mkilmanas那麼,應用程序的API返回,所以我沒有選擇。 –

回答

3

您可以使用內置於PHP中的DOMDocument

<?php 

$xml = <<<END 
<?xml version="1.0" encoding="utf-8" ?> 
<root> 
    <list> 
     <item no="1"> 
      <title>Item's 1 title</title> 
      <content>Some long content with <special>tags</special> inside</content> 
     </item> 
     <item no="2"> 
      <title>Item's 2 title</title> 
      <content>Some long content with <special>tags</special> inside</content> 
     </item> 
    </list> 
</root> 
END; 

$doc = new DOMDocument('1.0', 'UTF-8'); 
$doc->loadXML($xml); 

$nodes = $doc->getElementsByTagName('content'); 

foreach ($nodes as $node) 
{ 
    $temp_doc = new DOMDocument('1.0', 'UTF-8'); 

    foreach ($node->childNodes as $child) 
    $temp_doc->appendChild($temp_doc->importNode($child, true)); 

    echo $temp_doc->saveHTML(); // Outputs: Some long content with <special>tags</special> inside 
} 

要選擇頂級的「內容」的元素(如果裏面有「內容」的元素),你可以使用DOMXPath

$doc = new DOMDocument('1.0', 'UTF-8'); 
$doc->loadXML($xml); // $xml from the example above 

$xpath = new DOMXPath($doc); 

$nodes = $xpath->query('/root/list/item/content'); 

foreach ($nodes as $node) 
{ 
    $temp_doc = new DOMDocument('1.0', 'UTF-8'); 

    foreach ($node->childNodes as $child) 
    $temp_doc->appendChild($temp_doc->importNode($child, true)); 

    echo $temp_doc->saveHTML(); // Outputs: Some long content with <special>tags</special> inside 
} 
+0

不錯,如果文本節點包含標籤'內容'會怎麼樣? – ajreal

+0

@ajreal - 您可以使用DOMXPath來僅提取頂級「內容」標記。我會更新我的例子。 –

0

SimpleXML只是不支持混合內容(文本節點與元素節點作爲兄弟)。我建議你改用XMLReader

0

您可以使用SimpleXML的asXML函數。它將返回被調用的節點作爲xml字符串;

$xml = simplexml_load_file($file); 
foreach($xml->list->item as $item) { 
    $content = $item->contents->asXML(); 
    echo $content."\n"; 
} 

會打印:

<content>Some long content with <special>tags</special> inside</content> 
<content>Some long content with <special>tags</special> inside</content> 

這是一個有點難看,但那麼你可以夾出<content></content>用SUBSTR:

$content = substr($content,9,-10);