在PHP中解析XML内部的HTML标签

问题描述:

我试图在解析PHP中的http://uk.news.yahoo.com/rss时使用simplexml_load_string创建我自己的RSS源(学习目的)。我在阅读<description>标签内的HTML标签时遇到困难。在PHP中解析XML内部的HTML标签

到目前为止我的代码看起来是这样的:

$feed = file_get_contents('http://uk.news.yahoo.com/rss'); 
$rss = simplexml_load_string($feed); 

//for each element in the feed 
foreach ($rss->channel->item as $item) { 
    echo '<h3>'. $item->title . '</h3>'; 

     foreach($item->description as $desc){ 

      //how to read the href from the a tag??? 

      //this does not work at all 
      $tags = $item->xpath('//a'); 
      foreach ($tags as $tag) { 
       echo $tag['href']; 
      } 
     } 
} 

任何想法如何提取每个HTML标签?

感谢

描述的内容有其特殊的字符编码,所以它不是在XML中视为节点,而这只是一个字符串。您可以解码特殊字符,然后将HTML加载到DOMDocument中并执行任何您想要的操作。例如:

foreach ($rss->channel->item as $item) { 
    echo '<h3>'. $item->title . '</h3>'; 

     foreach($item->description as $desc){ 

      $dom = new DOMDocument(); 
      $dom->loadHTML(htmlspecialchars_decode((string)$desc)); 

      $anchors = $dom->getElementsByTagName('a'); 
      echo $anchors->item(0)->getAttribute('href'); 
     } 
} 

XPath也可用于DOMDocument,请参阅DOMXPath

+0

谢谢。我发现我很接近但不够近。这正是我所期待的。谢谢 – Adrian

+0

没问题,开心编码:) – MrCode

在这里做的最好的事情是使用的var_dump()函数在$项目。

feed = file_get_contents('http://uk.news.yahoo.com/rss'); 
$rss = simplexml_load_string($feed); 
foreach ($rss->channel->item as $item) { 
    var_dump($item); 
    exit; 
} 

一旦你这样做,你会看到你后面的值被称为“链接”。因此打印出来,你会使用下面的代码的网址:

echo $item->link; 
+0

但是,如果我只想获取Feed的说明,则此方法无效!因为我会在描述标签(例如image) – Adrian

+0

中获得所有内容,这是因为RSS中的实际“描述”元素包含图像。如果你只想要文字而不是图像,我会用strip_tags函数来包装整个描述。因此,打印出来的代码只是描述:echo strip_tags($ item-> description); –

+0

很酷。这工作(如你所说)仅用于描述(thx为此)。但是,如果我想要提取具有其属性的所有元素?假设在这种情况下,图像的“src”?或者可能是图像的宽度? – Adrian

RSS提要的<description>元素包含HTML。正如How to parse CDATA HTML-content of XML using SimpleXML?中所述,您需要获取该元素的节点值(HTML)并在附加解析器中对其进行解析。

accepted answer to the linked question已经显示了这一点非常详细,对于SimpleXML,它在这里不起什么作用,无论这个RSS提要是使用CDATA还是只使用像你的情况的实体。

$feed = file_get_contents('http://uk.news.yahoo.com/rss'); 
$rss = simplexml_load_string($feed); 
$dom = new DOMDocument(); // the HTML parser used for descriptions' HTML 

foreach ($rss->channel->item as $item) 
{ 
    echo '<h3>' . $item->title . '</h3>', "\n"; 

    foreach ($item->description as $desc) 
    { 
     $dom->loadHTML($desc); 

     $html = simplexml_import_dom($dom)->body; 

     echo $html->p->a['href'], "\n"; 
    } 
} 

输出例:

... 
<h3>Chantal nears hurricane strength in Caribbean</h3> 
http://uk.news.yahoo.com/chantal-nears-hurricane-strength-caribbean-220149771.html 
<h3>Placido Domingo In Hospital With Blood Clot</h3> 
http://uk.news.yahoo.com/placido-domingo-hospital-blood-clot-215427742.html 
<h3>Berlusconi's final tax fraud appeal hearing set for July 30</h3> 
http://uk.news.yahoo.com/berlusconis-final-tax-fraud-appeal-hearing-set-july-214714122.html 
<h3>China: Men Rescued From River Amid Floods</h3> 
http://uk.news.yahoo.com/china-men-rescued-river-amid-floods-213005159.html 
<h3>Snowden has not yet accepted asylum in Venezuela - WikiLeaks</h3> 
http://uk.news.yahoo.com/snowden-not-yet-accepted-asylum-venezuela-wikileaks-190332291.html 
<h3>Three US kidnap victims break silence</h3> 
http://uk.news.yahoo.com/three-us-kidnap-victims-release-thankyou-video-093832611.html 
... 

希望这有助于。与接受的答案相反,我认为没有理由申请htmlspecialchars_decode,实际上我很确定这会破坏事情。另外我的例子展示了如何通过展示如何在解析HTML之后将DOMNode转换回SimpleXMLElement来保持访问更多子元素的SimpleXML方式。

+0

嗨。谢谢你。我喜欢你的答案,因为它让我回到XML节点。感谢您花时间写下它。这两个答案帮助我了解如何访问这些标记(值信息)。再次感谢 – Adrian