2009-04-27 21 views
5

मेरे पास एक ऐसा फ़ंक्शन है जो php के DOMDocument का उपयोग करके स्ट्रिंग में एंकर 'href विशेषता को प्रतिस्थापित करता है। यहाँ एक टुकड़ा है:मैं एचपीएमएल इकाइयों को एन्कोडिंग से PHP के DOMDocument को कैसे रोकूं?

$doc  = new DOMDocument('1.0', 'UTF-8'); 
$doc->loadHTML($text); 
$anchors = $doc->getElementsByTagName('a'); 

foreach($anchors as $a) { 
    $a->setAttribute('href', 'http://google.com'); 
} 

return $doc->saveHTML(); 

समस्या यह है कि loadHTML ($ पाठ) doctype, एचटीएमएल, शरीर, आदि टैग में $ पाठ चारों ओर से घेरे है। मैं इस के आसपास loadHTML इस के बजाय() करने से काम कर की कोशिश की:

$doc  = new DOMDocument('1.0', 'UTF-8'); 
$node  = $doc->createTextNode($text); 
$doc->appendChild($node); 
... 

दुर्भाग्य से, यह सभी संस्थाओं को कूटबद्ध (एंकर शामिल)। क्या कोई इसे जानता है कि इसे कैसे बंद करें? मैंने पहले से ही दस्तावेज़ों को पूरी तरह से देखा है और इसे हैकिंग करने का प्रयास किया है, लेकिन इसे समझ नहीं सकता है।

धन्यवाद! :)

उत्तर

3
$ पाठ जगह धारक एंकर टैग

यदि इन जगह धारकों एक सख्त, अच्छी तरह से परिभाषित प्रारूप एक सरल चाल preg_replace या preg_replace_callback कर सकता है के साथ एक अनुवादित स्ट्रिंग है।
मैं सामान्य रूप से रेगेक्स के साथ एचटीएमएल दस्तावेज़ों के बारे में झुकाव का सुझाव नहीं देता, लेकिन एक छोटे से अच्छी तरह से परिभाषित सबसेट के लिए वे उपयुक्त हैं।

1

एक्सएमएल में केवल very few predefined entities है। आप सभी एचटीएमएल इकाइयों को कहीं और परिभाषित किया जाता है। जब आप loadhtml() का उपयोग करते हैं, तो इन इकाई परिभाषाओं को स्वचालित रूप से लोड किया जाता है, loadxml() (या कोई लोड() बिल्कुल नहीं) वे नहीं हैं।
createTextNode() वही करता है जो नाम बताता है। जो कुछ भी आप मूल्य के रूप में पास करते हैं उसे टेक्स्ट सामग्री के रूप में माना जाता है, मार्कअप के रूप में नहीं। अर्थात। यदि आप कुछ ऐसा पास करते हैं जिसका मार्कअप (<, >, ...) पर एक विशेष अर्थ है, तो यह एक तरीके से एन्कोड किया गया है कि एक पार्सर वास्तविक मार्कअप से टेक्स्ट को अलग कर सकता है (लेफ्टिनेंट, & gt ;,)

$ टेक्स्ट कहां से आता है? क्या आप वास्तविक एचटीएमएल दस्तावेज़ के भीतर प्रतिस्थापन नहीं कर सकते?

+0

लोड HTML, कोई इकाई अनुवाद नहीं होता है। मैं mb_substr ($ text, 122, -19) चलाकर समस्या को चारों ओर एक कमजोर तरीके से हैकिंग समाप्त कर दिया; $ doc-> saveHTML() से परिणाम पर। ओह! :) $ टेक्स्ट स्थान-धारक एंकर टैग के साथ एक अनुवादित स्ट्रिंग है, इसलिए प्रतिस्थापन रन टाइम के दौरान किया जाना चाहिए।मैं पूरे दस्तावेज़ को पार्स नहीं करना चाहूंगा क्योंकि केवल अनुवादित लिंक को पार्स करना मुश्किल होगा। हालांकि अच्छा विचार है। – thesmart

0

मैं एक कमजोर तरीके से इस हैकिंग समाप्त हो गया, बदल रहा है:

में
return $doc->saveHTML(); 

:

$text  = $doc->saveHTML(); 
return mb_substr($text, 122, -19); 

यह सभी अनावश्यक कचरा बाहर में कटौती, यह बदल रहा है:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" 
"http://www.w3.org/TR/REC-html40/loose.dtd"> <html><body><p> 
You can <a href="http://www.google.com">click here</a> to visit Google.</p> 
</body></html> 

इसमें:

You can <a href="http://www.google.com">click here</a> to visit Google. 

क्या कोई बेहतर कुछ समझ सकता है?

-1

ठीक है, यहां अंतिम समाधान है जिसके साथ मैं समाप्त हुआ। वोल्करके के सुझाव के साथ जाने का फैसला किया।

public static function ReplaceAnchors($text, array $attributeSets) 
{ 
    $expression = '/(<a)([\s\w\d:\/=_&\[\]\+%".?])*(>)/'; 

    if (empty($attributeSets) || !is_array($attributeSets)) { 
     // no attributes to set. Set href="#". 
     return preg_replace($expression, '$1 href="#"$3', $text); 
    } 

    $attributeStrs = array(); 
    foreach ($attributeSets as $attributeKeyVal) { 
     // loop thru attributes and set the anchor 
     $attributePairs = array(); 
     foreach ($attributeKeyVal as $name => $value) { 
      if (!is_string($value) && !is_int($value)) { 
       continue; // skip 
      } 

      $name    = htmlspecialchars($name); 
      $value    = htmlspecialchars($value); 
      $attributePairs[] = "$name=\"$value\""; 
     } 
     $attributeStrs[] = implode(' ', $attributePairs); 
    } 

    $i  = -1; 
    $pieces = preg_split($expression, $text); 
    foreach ($pieces as &$piece) { 
     if ($i === -1) { 
      // skip the first token 
      ++$i; 
      continue; 
     } 

     // figure out which attribute string to use 
     if (isset($attributeStrs[$i])) { 
      // pick the parallel attribute string 
      $attributeStr = $attributeStrs[$i]; 
     } else { 
      // pick the last attribute string if we don't have enough 
      $attributeStr = $attributeStrs[count($attributeStrs) - 1]; 
     } 

     // build a opening new anchor for this token. 
     $piece = '<a '.$attributeStr.'>'.preg_replace($expression, '$1 href="#"$3', $piece); 
     ++$i; 
    } 

    return implode('', $pieces); 

यह किसी को विभिन्न एंकर विशेषताओं के सेट के साथ फ़ंक्शन को कॉल करने की अनुमति देता है।