PHP DomDocument HTML操作 [英] PHP DomDocument HTML Manipulation

查看:116
本文介绍了PHP DomDocument HTML操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下HTML。

 < div id =container> 
< div id =current>当前Div< / div>
< / div>

在PHP中使用DomDocument时,我试图在div之前向HTML添加一个额外的div b
$ b

 < div id =container> 
< div id =new> New Div< / div>
< div id =current>当前Div< / div>
< / div>

当我使用下面的代码时,它似乎在div中添加了div,ID为当前,但在此div的内容之前。任何人都可以告诉我这是为什么,以及如何获得像上面的HTML一样的结果? (请参阅下面的HTML问题)



当前PHP

  $ doc = new DOMDocument(); 
$ doc-> formatOutput = true;

$ doc-> loadHTMLFile('index.html');

$ head = $ doc-> getElementById('current');
$ base = $ doc-> createElement('div','New Div');
$ base-> setAttribute('id','new');
echo $ doc-> saveHTML();

HTML问题

 < div id =container> 
< div id =当前>
< div id =new> New Div< / div>
当前Div
< / div>
< / div>

编辑:

PHP

  $ doc = new DOMDocument(); 
$ doc-> formatOutput = true;

$ doc-> loadHTMLFile('index.html');
$ container = $ doc-> getElementById('container');
$ current = $ doc-> getElementById('username');
$ new = $ doc-> createElement('div','New Div');

$ new-> setAttribute('id','new');
$ container-> insertBefore($ new,$ current);
echo $ doc-> saveHTML();

HTML

 < div id =container> 
< form method =postaction =>
< input type =textname =usernameid =username/>
< / form>
< / div>

错误:

 致命错误:未捕获异常'DOMException',其中'Not Found Error'
在index.php中:55堆栈跟踪:#0 index.php(55):
DOMNode-> insertBefore(Object(DOMElement),Object(DOMElement))


解决方案

您可以使用 DOMNode :: insertBefore()

 <?php 

$ doc = new DOMDocument ();
$ doc-> formatOutput = true;
$ doc-> loadHTMLFile('index.html');

$ container = $ doc-> getElementById('container');
$ current = $ doc-> getElementById('current');
$ new = $ doc-> createElement('div','New Div');

$ new-> setAttribute('id','new');
$ container-> insertBefore($ new,$ current);

var_dump($ doc-> saveHTML());

这产生:

 <!DOCTYPE html PUBLIC -  // W3C // DTD HTML 4.0 Transitional // ENhttp://www.w3.org/TR/REC-html40/loose.dtd\"> 
< html>
< body>
< div id =container>
< div id =new> New Div< / div>
< div id =current>当前Div< / div>
< / div>
< / body>
< / html>

希望这有助于:)

编辑



引用您报告的问题...我看到问题: input#username 不是 div#container 的直接子元素,它是 form 的直接子元素。因此,您需要将表单元素作为 DOMNode 对象,而不是它的父元素 div#容器。最简单的方法是在表格中添加一个id,并执行如下操作:

  $ form = $ doc-> getElementById('form'); 
$ username = $ doc-> getElementById('username');
$ username-> setAttribute('value','输入用户名!');

var_dump($ doc-> saveHTML());

这是基于以下HTML。请注意,表单元素有一个ID:

 < div id = 容器 > 
< form id =formmethod =postaction =>
< input type =textname =usernameid =username>
< / form>
< / div>

如果由于某种原因,您无法向表单元素添加id,则可以从<$ c

$ p $ //找到div#容器元素
$ container = $ doc-> getElementBy('id');
//找到所有div元素子元素的表单元素
$ forms = $ container-> getElementsByTagName('form');

if(0!== $ form-> length){
$ form = $ forms-> item(0);
}

//等等

编辑#2



我差点忘了XPath ...如果您想要更简洁/冒险,您可以使用 DOMXPath :: query() 来查找DOM节点:

  $ xpath = new DOMXPath($ doc); 
$ form = $ xpath-> query('body / div [@ id =container] / form') - > item(0);
$ input = $ xpath-> query('body // input [@ id =username]') - > item(0);

XPath查询语法相当神秘但功能强大,我不能说我是任何方式的专家,所以我不能说这些查询的效率。你也可以添加错误检查 - query 方法返回一个 DOMNodeList ,它有一个



最后值得注意的是, DOMDocument DOCTYPE html body 标签;这就是XPath查询从 body 传递的原因。


I have the following HTML.

<div id="container">
    <div id="current">Current Div</div>
</div>

Using DomDocument in PHP, I am trying to add an extra div to the HTML before the div with the id of "current".

<div id="container">
    <div id="new">New Div</div>
    <div id="current">Current Div</div>
</div>

When I use the following code, it appears to add the div inside the div with the id of "current", but before the content of this div.Can anyone tell me why this is and how I can get the results like the HTML above? (See HTML Issue Below)

Current PHP

$doc = new DOMDocument();
$doc->formatOutput = true;

$doc->loadHTMLFile('index.html');

$head = $doc->getElementById('current');
$base = $doc->createElement('div', 'New Div');
$base->setAttribute('id', 'new');
echo $doc->saveHTML();

HTML Issue

<div id="container">
    <div id="current">
        <div id="new">New Div</div>
        Current Div
    </div>
</div>

EDIT:

PHP

$doc = new DOMDocument();
$doc->formatOutput = true;

$doc->loadHTMLFile('index.html');
$container = $doc->getElementById('container');
$current = $doc->getElementById('username');
$new = $doc->createElement('div', 'New Div');

$new->setAttribute('id', 'new');
$container->insertBefore($new, $current);
echo $doc->saveHTML();

HTML

<div id="container">
    <form method="post" action="">
        <input type="text" name="username" id="username" />
    </form>
</div>

Error:

Fatal error: Uncaught exception 'DOMException' with message 'Not Found Error' 
in index.php:55 Stack trace: #0 index.php(55): 
DOMNode->insertBefore(Object(DOMElement), Object(DOMElement))

解决方案

You can use DOMNode::insertBefore():

<?php

$doc = new DOMDocument();
$doc->formatOutput = true;
$doc->loadHTMLFile('index.html');

$container = $doc->getElementById('container');
$current = $doc->getElementById('current');
$new = $doc->createElement('div', 'New Div');

$new->setAttribute('id', 'new');
$container->insertBefore($new, $current);

var_dump($doc->saveHTML());

This yields:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
    <body>
        <div id="container">
            <div id="new">New Div</div>
            <div id="current">Current Div</div>
        </div>
    </body>
</html>

Hope this helps :)

EDIT

Referring to your reported issue... I see the problem: input#username is not an immediate child of div#container, it's an immediate child of form. So you need to get the form element as a DOMNode object, not its parent div#container. Easiest way to do this is add an id to the form and do something like this:

$form = $doc->getElementById('form');
$username = $doc->getElementById('username');
$username->setAttribute('value', 'Enter username!');

var_dump($doc->saveHTML());

This is based on the the following HTML. Note the form element has an id:

<div id="container">
    <form id="form" method="post" action="">
        <input type="text" name="username" id="username">
    </form>
</div>

If for some reason you cannot add an id to the form element, you can traverse from div#container like so:

// find div#container element
$container = $doc->getElementBy('id');
// find all form elements that are children of div#container
$forms = $container->getElementsByTagName('form');

if (0 !== $forms->length) {
   $form = $forms->item(0);
}

// etc.

EDIT #2

I almost forgot XPath... If you want to get more succinct/adventurous you can use DOMXPath::query() to find DOM nodes:

$xpath = new DOMXPath($doc);
$form  = $xpath->query('body/div[@id="container"]/form')->item(0);
$input = $xpath->query('body//input[@id="username"]')->item(0);

The XPath query syntax is pretty cryptic but powerful, I cannot say I'm an expert by any means, so I cannot speak for the efficiency of these queries. Also you might want to add error checking - the query method returns a DOMNodeList which has a length property.

Finally it's worth noting that DOMDocument decorates your HTML fragment with a DOCTYPE and html and body tags; this is why the XPath query traverses from body.

这篇关于PHP DomDocument HTML操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆