2011-08-28 15 views
5

मैं डोम दस्तावेज़ का उपयोग करता है इस तरह डेटाबेस से एचटीएमएल लोड करने के लिए अनदेखी हो रही textContent:पीएचपी Dom दस्तावेज: स्क्रिप्ट टैग और टिप्पणियों

$doc = new DOMDocument(); 
@$doc->loadHTML($data); 
$doc->encoding = 'utf-8'; 
$doc->saveHTML(); 

तो मैं इन करके शरीर पाठ मिलता है:

$bodyNodes = $doc->getElementsByTagName("body"); 
$words = htmlspecialchars($bodyNodes->item(0)->textContent); 

जिन शब्दों को मैंने प्राप्त किया है उनमें <body> में सबकुछ शामिल है। <scripts> जैसी चीजें भी शामिल थीं। मैं उन्हें कैसे हटा सकता हूं और केवल वास्तविक पाठ सामग्री को कैसे रखूं?

+0

आप ' में हर तत्व' की पुनरावर्ती निकालने पाठ सामग्री मतलब है? –

+0

यैप केवल टेक्स्ट सामग्री जो सार्थक हैं, जावास्क्रिप्ट या अन्य HTML टिप्पणियां या आदि को छोड़कर जो उपयोगी डेटा नहीं हैं। – nuttynibbles

उत्तर

5

आपको सभी नोड्स पर जाना होगा और अपना टेक्स्ट वापस करना होगा। अगर कुछ अन्य नोड होते हैं, तो उन पर भी जाएं।

यह इस बुनियादी पुनरावर्ती एल्गोरिदम के साथ किया जा सकता:

extractNode: 
    if node is a text node or a cdata node, return its text 
    if is an element node or a document node or a document fragment node: 
     if it’s a script node, return an empty string 
     return a concatenation of the result of calling extractNode on all the child nodes 
    for everything else return nothing 

कार्यान्वयन:

function extractText($node) {  
    if (XML_TEXT_NODE === $node->nodeType || XML_CDATA_SECTION_NODE === $node->nodeType) { 
     return $node->nodeValue; 
    } else if (XML_ELEMENT_NODE === $node->nodeType || XML_DOCUMENT_NODE === $node->nodeType || XML_DOCUMENT_FRAG_NODE === $node->nodeType) { 
     if ('script' === $node->nodeName) return ''; 

     $text = ''; 
     foreach($node->childNodes as $childNode) { 
      $text .= extractText($childNode); 
     } 
     return $text; 
    } 
} 

यह दिया $ नोड के textContent वापस आ जाएगी, स्क्रिप्ट टैग और टिप्पणियों की अनदेखी।

$words = htmlspecialchars(extractText($bodyNodes->item(0))); 

इसे यहाँ का प्रयास करें: http://codepad.org/CS3nMp7U

+0

यह काम करता है। यदि आप दिमाग में नहीं हैं, तो क्या आप कोड समझा सकते हैं? – nuttynibbles

+0

मैंने एल्गोरिदम – arnaud576875

5

आप इस के लिए XPath उपयोग कर सकते हैं। आप

$html = <<< HTML 
<p> 
    test<span>foo<b>bar</b> 
</p> 
<script> 
    ignored 
</script> 
<!-- comment is ignored --> 
<p>test</p> 
HTML; 

बस query सभी text nodes कि not children of a script tag और do not evaluate to an empty string नहीं हैं:

एचटीएमएल उधार के ऊपर अपने उदाहरण के लिए इस्तेमाल किया Arnaud। आप यह भी सुनिश्चित करेंगे कि आप preserveWhiteSpace नहीं हैं, इसलिए फ़ॉर्मेटिंग के लिए उपयोग किए जाने वाले व्हाइटस्पेस को नहीं माना जाता है।

$dom = new DOMDocument; 
$dom->preserveWhiteSpace = false; 
$dom->loadHtml($html); 

$xp = new DOMXPath($dom); 
$nodes = $xp->query('/html/body//text()[ 
    not(ancestor::script) and 
    not(normalize-space(.) = "") 
]'); 

foreach($nodes as $node) { 
    var_dump($node->textContent); 
} 

इच्छा उत्पादन (demo)

string(10) " 
    test" 
string(3) "foo" 
string(3) "bar" 
string(4) "test" 
+0

का त्वरित विवरण जोड़ा है यह फ़ंक्शन मदद करता है। यह वास्तव में शब्दों की वाक्य को एक स्ट्रिंग के रूप में पहचानने और विभाजित करने में सक्षम है। – nuttynibbles

+0

@nuttynibbles यह शब्द, न ही वाक्यों को पहचानता है। एक्सपीएथ एक्सएमएल के लिए एक क्वेरी भाषा है। इसकी संरचना के बारे में, किसी XML दस्तावेज़ की सामग्री के बारे में कोई जानकारी नहीं है। [डीओएम अवधारणाओं के परिचय के लिए मेरा जवाब यहां देखें] (http://stackoverflow.com/questions/4979836/noob-question-about-domdocument-in-php/4983721#4983721) – Gordon

संबंधित मुद्दे