PHP DOM uygulamasında belirli bir DOMNode'un innerHTML'sini almak için hangi işlevi kullanıyorsunuz? Birisi güvenilir çözüm verebilir mi?
Tabii ki externalHTML de işe yarar.
PHP DOM uygulamasında belirli bir DOMNode'un innerHTML'sini almak için hangi işlevi kullanıyorsunuz? Birisi güvenilir çözüm verebilir mi?
Tabii ki externalHTML de işe yarar.
Yanıtlar:
Karşılaştırma ile bu güncellenmiş varyantını PHP Manual Kullanıcı Not # 89718 :
<?php
function DOMinnerHTML(DOMNode $element)
{
$innerHTML = "";
$children = $element->childNodes;
foreach ($children as $child)
{
$innerHTML .= $element->ownerDocument->saveHTML($child);
}
return $innerHTML;
}
?>
Misal:
<?php
$dom= new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->load($html_string);
$domTables = $dom->getElementsByTagName("table");
// Iterate over DOMNodeList (Implements Traversable)
foreach ($domTables as $table)
{
echo DOMinnerHTML($table);
}
?>
DOMDocument
. Ayrıca bir değiştirmek isteyebilirsiniz trim
bir ile ltrim
satır aralıklarında gibi boşluk biraz korumak için (hatta tamamen kaldırmak).
DOMElement
yerine a beklemek için işlev bildirimini değiştirmek zorunda kaldım . Başkasının tuzağına düşmesi ihtimaline karşı. DOMNode
DOMDocument::getElementById()
html
Bir elemanın döndürülmesi için C14N () kullanabilirsiniz :
$dom = new DOMDocument();
$dom->loadHtml($html);
$x = new DOMXpath($dom);
foreach($x->query('//table') as $table){
echo $table->C14N();
}
Haim Evgi'nin cevabının basitleştirilmiş bir versiyonu:
<?php
function innerHTML(\DOMElement $element)
{
$doc = $element->ownerDocument;
$html = '';
foreach ($element->childNodes as $node) {
$html .= $doc->saveHTML($node);
}
return $html;
}
Örnek kullanım:
<?php
$doc = new \DOMDocument();
$doc->loadHTML("<body><div id='foo'><p>This is <b>an <i>example</i></b> paragraph<br>\n\ncontaining newlines.</p><p>This is another paragraph.</p></div></body>");
print innerHTML($doc->getElementById('foo'));
/*
<p>This is <b>an <i>example</i></b> paragraph<br>
containing newlines.</p>
<p>This is another paragraph.</p>
*/
preserveWhiteSpace
Veya ayarlamanıza gerek yok formatOutput
.
Trincot'un güzel versiyonuna ek olarak array_map
ve ile implode
ama bu sefer array_reduce
:
return array_reduce(
iterator_to_array($node->childNodes),
function ($carry, \DOMNode $child) {
return $carry.$child->ownerDocument->saveHTML($child);
}
);
Yine de anlamıyorum, neden reduce()
dizileri ve yineleyicileri kabul eden bir yöntem olmadığını .
function setnodevalue($doc, $node, $newvalue){
while($node->childNodes->length> 0){
$node->removeChild($node->firstChild);
}
$fragment= $doc->createDocumentFragment();
$fragment->preserveWhiteSpace= false;
if(!empty($newvalue)){
$fragment->appendXML(trim($newvalue));
$nod= $doc->importNode($fragment, true);
$node->appendChild($nod);
}
}
İşte Drupella'nın php.net'teki bu yorumuna dayanan ve projem için iyi sonuç veren başka bir yaklaşım . Alt düğümler üzerinde açıkça yinelemek yerine, innerHTML()
yeni bir oluşturarak DOMDocument
, içe aktararak ve ona hedef düğümü ekleyerek tanımlar .
Bu yardımcı işlevi tanımlayalım:
function innerHTML( \DOMNode $n, $include_target_tag = true ) {
$doc = new \DOMDocument();
$doc->appendChild( $doc->importNode( $n, true ) );
$html = trim( $doc->saveHTML() );
if ( $include_target_tag ) {
return $html;
}
return preg_replace( '@^<' . $n->nodeName .'[^>]*>|</'. $n->nodeName .'>$@', '', $html );
}
burada dış hedef etiketi ikinci giriş argümanı aracılığıyla dahil edebilir / hariç tutabiliriz.
Burada, "ilk" id özelliği tarafından verilen bir hedef etiket için iç HTML'yi çıkarıyoruz:
$html = '<div id="first"><h1>Hello</h1></div><div id="second"><p>World!</p></div>';
$doc = new \DOMDocument();
$doc->loadHTML( $html );
$node = $doc->getElementById( 'first' );
if ( $node instanceof \DOMNode ) {
echo innerHTML( $node, true );
// Output: <div id="first"><h1>Hello</h1></div>
echo innerHTML( $node, false );
// Output: <h1>Hello</h1>
}
Canlı örnek:
http://sandbox.onlinephpfunctions.com/code/2714ea116aad9957c3c437d46134a1688e9133b8
Eski sorgu, ancak bunu yapmak için yerleşik bir yöntem var. Sadece hedef düğümü iletin DomDocument->saveHtml()
.
Tam örnek:
$html = '<div><p>ciao questa è una <b>prova</b>.</p></div>';
$dom = new DomDocument($html);
@$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$node = $xpath->query('.//div/*'); // with * you get inner html without surrounding div tag; without * you get inner html with surrounding div tag
$innerHtml = $dom->saveHtml($node);
var_dump($innerHtml);
Çıktı: <p>ciao questa è una <b>prova</b>.</p>