PHPDOM搜索HTML并指定IMG在P中的位置

PHPDOM搜索HTML并指定IMG在P中的位置,php,html,dom,Php,Html,Dom,我想解析一些从ckeditor提交的HTML。发布的HTML如下所示: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">#012<html><body><p>Text Before <img alt="HAMBURGER" height="20" src="/sites/all/m

我想解析一些从ckeditor提交的HTML。发布的HTML如下所示:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">#012<html><body><p>Text Before <img alt="HAMBURGER" height="20" src="/sites/all/modules/ckeditor/plugins/apoji/images/emoji-E120.png" title="HAMBURGER" width="20"> Text After</p></body></html>
$DOM = new DOMDocument;
$DOM->loadHTML($input);

$items = $DOM->getElementsByTagName('*');
foreach ($items as $item) {
    switch ($item->nodeName) {
    case "p":
        $sms .= $item->nodeValue."\n";
        break;
    case "img":
        $img_out .= "IMG Attr: ".$item->getAttribute('title')."\n";
        break;
    }
}
我的目标是创建一个纯文本字符串,根据其标题替换图像,因此我将创建一个类似以下的字符串:

Text Before HAMBURGER Text After
Text Before HAMBURGER Text After
我已经开始走DOM路线,因为这似乎是最好的方法,但现在我有两个问题:

  • 如果我像上面那样在文档上循环,IMG会在文本之后结束, 不在中间。我怎样才能避免这种情况
  • 从DOM文档中提取所有纯文本的最佳方法是保持项目的顺序(链接到第1点)
  • 提前感谢任何能为我提供一些信息的人。

    您可以使用查找特定项目,然后使用新节点

    例如

    您可以使用查找特定项目,然后使用新节点

    例如


    您可以简单地使用正则表达式替换:

    <?php
    $text = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">#012<html><body><p>Text Before <img alt=\"HAMBURGER\" height=\"20\" src=\"/sites/all/modules/ckeditor/plugins/apoji/images/emoji-E120.png\" title=\"HAMBURGER\" width=\"20\"> Text After</p></body></html>";
    $match = array();
    preg_match("/<p[^>]*>(.*(?=<\/p))/i", $text, $match);
    echo preg_replace("/<img[^>]*title=\"([^\"]+)\"[^>]*>/i", "$1", $match[1]);
    ?>
    

    您可以简单地使用正则表达式替换:

    <?php
    $text = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">#012<html><body><p>Text Before <img alt=\"HAMBURGER\" height=\"20\" src=\"/sites/all/modules/ckeditor/plugins/apoji/images/emoji-E120.png\" title=\"HAMBURGER\" width=\"20\"> Text After</p></body></html>";
    $match = array();
    preg_match("/<p[^>]*>(.*(?=<\/p))/i", $text, $match);
    echo preg_replace("/<img[^>]*title=\"([^\"]+)\"[^>]*>/i", "$1", $match[1]);
    ?>
    
    
    
    我的目标是创建一个纯文本字符串,根据其标题替换图像,因此我将创建一个类似以下的字符串:

    Text Before HAMBURGER Text After
    
    Text Before HAMBURGER Text After
    
    一个选项是使用XPath查询选择所需的文本/标题,并输出它们各自的值

    $html = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"><html><body><p>Text Before<img alt="HAMBURGER" height="20" src="/sites/all/modules/ckeditor/plugins/apoji/images/emoji-E120.png" title="HAMBURGER" width="20">Text After</p></body></html>';
    
    $doc = new DOMDocument;
    $doc->loadHTML($html);
    
    $xpath = new DOMXPath($doc);
    $nodes = $xpath->query('/html/body//text() | /html/body//img/@title');
    
    $text = '';
    foreach ($nodes as $node) {
        $text .= $node->nodeValue . ' ';
    }
    
    echo $text; // Text Before HAMBURGER Text After 
    
    $html='文本前文本后文本;
    $doc=新文档;
    $doc->loadHTML($html);
    $xpath=新的DOMXPath($doc);
    $nodes=$xpath->query('/html/body//text()|/html/body//img/@title');
    $text='';
    foreach($node作为$node){
    $text.=$node->nodeValue'';
    }
    echo$text;//汉堡包前文本后文本
    
    我的目标是创建一个纯文本字符串,根据其标题替换图像,因此我将创建一个类似以下的字符串:

    Text Before HAMBURGER Text After
    
    Text Before HAMBURGER Text After
    
    一个选项是使用XPath查询选择所需的文本/标题,并输出它们各自的值

    $html = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"><html><body><p>Text Before<img alt="HAMBURGER" height="20" src="/sites/all/modules/ckeditor/plugins/apoji/images/emoji-E120.png" title="HAMBURGER" width="20">Text After</p></body></html>';
    
    $doc = new DOMDocument;
    $doc->loadHTML($html);
    
    $xpath = new DOMXPath($doc);
    $nodes = $xpath->query('/html/body//text() | /html/body//img/@title');
    
    $text = '';
    foreach ($nodes as $node) {
        $text .= $node->nodeValue . ' ';
    }
    
    echo $text; // Text Before HAMBURGER Text After 
    
    $html='文本前文本后文本;
    $doc=新文档;
    $doc->loadHTML($html);
    $xpath=新的DOMXPath($doc);
    $nodes=$xpath->query('/html/body//text()|/html/body//img/@title');
    $text='';
    foreach($node作为$node){
    $text.=$node->nodeValue'';
    }
    echo$text;//汉堡包前文本后文本
    
    您能使用JavaScript吗?jQuery很容易处理这个问题,然后您可以通过AJAX提交它。所以您真正的问题是“如何用它的title属性替换IMG元素”,对吗?标记的可能副本总是那么简单还是有更复杂的情况?您能使用JavaScript吗?jQuery很容易处理这个问题,然后您可以通过AJAX提交。所以您真正的问题是“如何用标题属性替换IMG元素”,对吗?标记的可能重复是因为您的标记总是那么简单还是有更复杂的情况?我不认为他试图替换任何东西,相反,看起来他只是想按文档顺序获取所有文本和图像标题内容的字符串。@Salath:是的,听起来不错(在问题的上下文中)+1作为你的回答……我认为他并没有试图替换任何内容,相反,他似乎只是想按文档顺序获取所有文本和图像标题内容的字符串。@salathe:是的,听起来不错(在问题的上下文中)+1.谢谢你的回答。。。如果HTML的结构像给定的例子一样简单,正则表达式就可以很好地工作。我认为可以肯定的是,这将不是一个已知的、有限的案例。如果HTML的结构像给定的例子一样简单,正则表达式就可以很好地工作。我认为可以安全地假设这不会是一个已知和有限的案例。谢谢@salathe,我喜欢这个解决方案!最后我使用了这样一行:
    $newitem=newdomelement('div',$item->getAttribute('title')$item->parentNode->replaceChild($newitem,$item)和我后面使用的代码一样:
    $html=$DOM->saveHTML()$html=substr(带标签($html),1)(是的,不太理想),但我认为你的方法会给我一个更简洁的解决方案,非常感谢!谢谢@salathe,我喜欢这个解决方案!最后我使用了这样一行:
    $newitem=newdomelement('div',$item->getAttribute('title')$item->parentNode->replaceChild($newitem,$item)和我后面使用的代码一样:
    $html=$DOM->saveHTML()$html=substr(带标签($html),1)(是的,不太理想),但我认为你的方法会给我一个更简洁的解决方案,非常感谢!