PHP - 内部使用HTML元素解析XML

时间:2014-08-14 15:34:25

标签: php html xml

我试图读取在元素中包含HTML的XML。它没有包含在CDATA标签中,这是问题,因为我使用的任何XML解析器都试图将其解析为XML。

XML中死亡的地方:

<item>
  <title>Title text <img src="https://abs.twimg.com/emoji/v1/72x72/1f525.png" draggable="false" alt="" aria-label="Emoji: Fire"></title>
</item>

错误讯息:

Warning: XMLReader::readOuterXml(): (xml file here) parser error : Opening and ending tag mismatch: img line 1 and title in (php file here)

我知道如何从XML元素中获取HTML,但解析器并不喜欢它是一个开放标记这样的事实,它无法找到结束标记,所以它会死掉而我无法再进一步了。

现在,我实际上并不需要<title>元素,所以如果有办法忽略它,那就可以了,因为我需要的信息只在{{1}的两个子节点中父母。

如果有人能看到解决方法,那就太棒了。

更新

使用Christian Gollhardt的建议,我设法将XML加载到一个对象中,但是我遇到的问题与我从<item>元素获取CDATA之前遇到的问题相同。

这是我应该得到的CDATA:

<description>

这就是我最终的结果:

<description> <![CDATA[<a href="https://twitter.com/menomatters" >@menomatters</a> <a href="https://twitter.com/physicool1" >@physicool1</a> will chill my own &quot;personal summer&quot;. <img src="https://abs.twimg.com/emoji/v1/72x72/1f525.png" draggable="false" alt="" aria-label="Emoji: Fire"><img src="https://abs.twimg.com/emoji/v1/72x72/2600.png" draggable="false" alt="☀️" aria-label="Emoji: Black sun with rays">]]> </description>

再次关闭代码会出现问题吗?

1 个答案:

答案 0 :(得分:2)

看看DOMDocument。你可以直接使用它,也可以编写一个函数,给你一个干净的文件。


清洁方法:

function tidyXml($xml) {
    $doc = new DOMDocument();
    if (@$doc->loadHTML($xml)) {
        $output = '';
        //Dom Document creates <html><body><myxml></body></html>, so we need to remove it
        foreach ($doc->getElementsByTagName('body')->item(0)->childNodes as $child) {
            $output .= $doc->saveXML($child);
        }
        return $output;
    } else {
        throw new Exception('Document can not be cleaned');
    }
}

function getSimpleXml($xml) {
    return new SimpleXMLElement(tidyXml($xml));
}

<强>实施

$xml= '<item><title>Title text <img src="https://abs.twimg.com/emoji/v1/72x72/1f525.png" draggable="false" alt="�" aria-label="Emoji: Fire"></title></item>';
$myxml = getSimpleXml($xml);

$titleNodeCollection =$myxml->xpath('/item/title');

foreach ($titleNodeCollection as $titleNode) {
    $titleText    = (string)$titleNode;
    $imageUrl     = (string)$titleNode->img['src'];
    $innerContent = str_replace(['<title>', '</title>'], '', $titleNode->asXML());

    var_dump($titleText, $imageUrl, $innerContent);
}

享受!