2011-03-24 121 views
1

嗨, $form持有该...php DOMDocument:表单元素的完整转换?包装和删除?

<form method="post" action=""> 
    <input type="hidden" name="ip" value="127.0.0.1"> 
    <label for="s2email">Your Email</label> 
    <input type="text" name="email" id="s2email" value="email..." size="20" onfocus="if (this.value == 'email...') {this.value = '';}" onblur="if (this.value == '') {this.value = 'email...';}"> 
    <input type="submit" name="subscribe" value="Subscribe"> 
    <input type="submit" name="unsubscribe" value="Unsubscribe"> 
</form> 

因为我不知道什么是可能与DOMDocument类,我需要寻求帮助。 我实际上有两件事情需要在上面的$ form上转换。

1.)label-s2email and its input#sd-email应该被包装在一个<div class="name"> 是甚至可以选择这两个(通过id或for-attribute)并将这两个包装到一个div?

2.)是否可以使用php删除onfocus和onblur属性?

感谢你的帮助

+0

*(相关)* [最佳方法解析HTML](http://stackoverflow.com/questions/3577641/best-methods-to-parse-html/3577662#3577662)和[关于'DOMDocument'的Noob问题在PHP中](http://stackoverflow.com/questions/4979836/noob-question-about-domdocument-in-php/4983721#4983721) – Gordon 2011-03-24 09:27:14

回答

2

因为我无法找到一个合适的重复,说明如何用DOM包节点,这里是解决方案:

// Setup DOMDocument and XPath 
$dom = new DOMDocument; 
$dom->loadHTML($form); 
$xpath = new DOMXPath($dom); 

// Create <DIV> with class attribute name 
$div = $dom->createElement('div'); 
$div->setAttribute('class', 'name'); 

// Find <input id="s2email"> and remove event attributes 
$input = $xpath->query('/html/body/form/input[@id="s2email"]')->item(0); 
$input->removeAttribute('onfocus'); 
$input->removeAttribute('onblur'); 

// Find <label for="s2email"> and insert new DIV before that 
$label = $xpath->query('/html/body/form/label[@for="s2email"]')->item(0); 
$label->parentNode->insertBefore($div, $label); 

// Move <label> and <input> into the new <div> 
$div->appendChild($label); 
$div->appendChild($input); 

// Echo the <form> outer HTML 
echo $dom->saveHTML($dom->getElementsByTagName('form')->item(0)); 

上面的代码将产生(live demo):

<form method="post" action=""> 
    <input type="hidden" name="ip" value="127.0.0.1"><div class="name"> 
<label for="s2email">Your Email</label><input type="text" name="email" id="s2email" value="email..." size="20"> 
</div> 
    <input type="submit" name="subscribe" value="Subscribe"><input type="submit" name="unsubscribe" value="Unsubscribe"> 
</form> 

注意为了通过一个节点到saveHTML,你需要PHP 5.3.6。见

对于之前可能的解决方法。

+0

正是我想要做的事情,完美。我使用saveXML工作。 – matt 2011-03-24 13:42:36

+0

如果表单存在,是否有机会查询?因为一旦我提交页面的表单重新加载并且没有表单。在这种情况下,我的控制台会抛出错误,因为表单上的所有操作都无法完成,也没有发现任何操作。 – matt 2011-03-24 13:46:36

+0

好吧,最简单的方法是使用'strpos'并在加载DOM之前检查$ form是否包含“ Gordon 2011-03-24 13:52:33

0

懒惰的解决办法是使用phpQuery或QueryPath这允许:在这种情况下,你可以直接使用的DOMDocument

print qp($html) 
    ->find("*[onfocus], *[onblur]")->removeAttr("onblur")->removeAttr("onfocus") 
    ->top()->find("label[for=s2email], input#s2email")->wrapAll("<div class='name'></div>") 
    ->top("form")->xml(); 

虽然。只有包装部分会更精致一些。如果您将<label>围绕<input>而不是使用for=name=关系,则可以简化此操作。