【问题标题】:Manipulate HTML from php从 php 操作 HTML
【发布时间】:2011-05-24 13:22:07
【问题描述】:

我有一个 html 文件 index.php 我想将 <div> 中的内容与该文件的类 main 一起替换为另一个文本。我怎样才能做到这一点?

html 中的示例内容:

<div class="main">
Replace this text with some code!
</div>

我想使用 php 获取此 div 中的内容并将其替换为其他内容。但我不知道如何做到这一点。

更新: 我知道使用 javascript 的客户端技巧。我想做这个服务器端。该文件将是 html 而不是 php。所以我认为我必须在 php 中打开 html 并执行此操作,尽管我不知道如何操作。

这可以用 xpath 或 html dom 解析器或其他东西来完成吗?谷歌搜索给了我这些术语,但我不知道它们实际上是什么。

【问题讨论】:

标签: php html dom html-manipulation


【解决方案1】:

您使用以下方式读取文件:

$fileContents=file_get_contents($file_path);

http://php.net/manual/en/function.file-get-contents.php

然后你搜索替换div内容:

$newHtmlContent=preg_replace("/<div class=\"main\">(.*)</div>/i",'<div class="main">Some text here</div>',$fileContents);

http://php.net/manual/en/function.preg-replace.php

我的正则表达式有点生疏,但你可以在这里舀一下: http://www.regular-expressions.info/tutorial.html

然后保存新的内容:

file_put_contents($file_path,$newHtmlContent);

http://www.php.net/manual/en/function.file-put-contents.php

或者您可以使用以下方法解析文件: http://simplehtmldom.sourceforge.net/ 但它必须格式正确。

我会推荐这个版本,因为如果主 div 的内容是另一个 div,上述将失败...

【讨论】:

  • 如果有 2 类
  • 您有时可以使用正则表达式来获得良好的效果,但它们通常是用于重写标记文档等树状结构的笨拙工具。通常值得考虑使用真正的标记解析器。
  • 这取决于,正则表达式方法可以大大改进,并且在您的情况下可以很好地工作,我现在没有时间挖掘更好的表达式。在这种情况下,如果有 2 个类名,它就不能使用那个确切的正则表达式。尝试使用 html 解析器...
  • 这必须灵活,以便我可以将它与具有不同类的不同 html 文件一起使用。
  • 然后,我建议尝试使用提供的 HTML 解析器,我在答案中将其加粗..
【解决方案2】:

如果它只需要包含一个静态片段

<div class="main">
<?php readfile ('path/to/some/file'); ?>
</div>

如果需要包含另一个 PHP 脚本的输出

<div class="main">
<?php include ('path/to/some/file') ?>
</div>

【讨论】:

  • 它不会是要包含的 php 文件。它将是一个静态 html 文件。
【解决方案3】:

您可以使用 PHP 的 DOM 类/函数来执行此操作。

首先创建/加载您的文档:

$d = new DOMDocument();
$d->loadHTML($yourWellFormedHTMLString);

然后,您需要找到要更改的文档节点。您可以使用 XPath 做到这一点:

$xpathsearch = new DOMXPath($d);
$nodes = $xpathsearch->query('//div[contains(@class,'main')]');  

然后你会想要遍历匹配的节点,并在里面创建新的节点:

foreach($nodes as $node) {
    $newnode = $d->createDocumentFragment();
    $newnode->appendXML($yourCodeYouWantToFillIn);
    $node->appendChild($newnode);
}

如果您不介意在开发的早期阶段使用库,请查看CAST(内容寻址样式模板)。它几乎就是按照您所描述的那样设计的,如果不出意外,您可以查看源代码以查看示例。

(注意:我相信精明的人会注意到 //div[contains(@class,'main')]完全相当于 CSS 选择器 div.main ... 因为 class 属性可以包含多个类。这样做precisely 已经够笨拙了没错。或者,只是更多地使用 ids 而不是类。:)

【讨论】:

  • loadHtml(不同于loadXml)不需要$yourWellFormedHTMLString。它可以解析现实世界中损坏的 HTML。
  • 就像这个解决方案的注释一样,如果有人偶然发现它:正如@weston-c 所提到的,查询不会只返回那些具有“main”类的元素,而是返回所有元素类名包含“main”。所以 class="maintain" 也被返回。相反,如果你使用 //div[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')],你可以使查询更精确。它也比答案链接中提供的解决方案要容易一些......希望这会有所帮助。
猜你喜欢
相关资源
最近更新 更多
热门标签