2010-11-05 83 views
3

在下面的foreach中,我需要解析關鍵字$ node.TextContent並在其周圍包圍粗體標籤。這可能與DOM?怎麼樣?DOM node.textContent解析和替換

$myContent ="<h1>This word should not be replaced: TEST</h1>. But this one should be replaced: test"; 

$dom = new DOMDocument; 
$dom->loadHTML(strtolower($myContent)); 
$xPath = new DOMXPath($dom); 
foreach($xPath->query("//text()[contains(.,'test') and not(ancestor::h1)]") as $node) 
    { 
     /*need to do a replace on each occurrence of the word "test" 
     in $node->textContent here so that it becomes <b>test</b>. How? */ 
    } 

呼應$dom->saveHTML應該產生:

<h1>This word should not be replaced: TEST</h1>. 
But this one should be replaced: <b>test</b>" 
+0

只要您輸入「DOM」的輸入,就不能使用'$ dom-> saveHTML'來實現輸出。在這裏看到我對你的問題的回答[如何用PHP進行不區分大小寫的XPath節點測試](http://stackoverflow.com/questions/4046022/parse-content-for-appearance-of-a-keyword-inside-h1 -h2-and-h3-heading-tags)或[純XPath 1.0解決方案](http://stackoverflow.com/questions/3238989/case-insensitive-xpath-searching-in-php) – Gordon 2010-11-05 23:01:15

+0

好問題,+ 1。 Seemy回答了完整的XSLT 1.0解決方案。:) – 2010-11-05 23:14:10

回答

1

編輯:作爲@LarsH已經注意到,我沒有注意,更換應在大膽的要求。

有兩種簡單的方法可以解決這個問題:

.1。 在改造替換

<xsl:value-of select="$pRep"/> 

<b><xsl:value-of select="$pRep"/></b> 

0.2。 通行證作爲pReplacement參數不僅"ABC"<b>ABC</b>

這XSLT 1.0轉化的值:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="pTarget" select="'test'"/> 
<xsl:param name="pReplacement" select="'ABC'"/> 

<xsl:variable name="vCaps"  select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/> 
<xsl:variable name="vLowecase" select="'abcdefghijklmnopqrstuvwxyz'"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="text()[not(ancestor::h1)]"> 
    <xsl:call-template name="replaceCI"> 
    <xsl:with-param name="pText" select="."/> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template name="replaceCI"> 
    <xsl:param name="pText"/> 
    <xsl:param name="pTargetText" select="$pTarget"/> 
    <xsl:param name="pRep" select="$pReplacement"/> 

    <xsl:variable name="vLowerText" 
     select="translate($pText, $vCaps, $vLowecase)"/> 
    <xsl:choose> 
    <xsl:when test= 
    "not(contains($vLowerText, $pTargetText))"> 
    <xsl:value-of select="$pText"/> 
    </xsl:when> 
    <xsl:otherwise> 
    <xsl:variable name="vOffset" select= 
    "string-length(substring-before($vLowerText, $pTargetText))"/> 

    <xsl:value-of select="substring($pText,1,$vOffset)"/> 

    <xsl:value-of select="$pRep"/> 

    <xsl:call-template name="replaceCI"> 
    <xsl:with-param name="pText" select= 
    "substring($pText, $vOffset + string-length($pTargetText)+1)"/> 
    <xsl:with-param name="pTargetText" select="$pTargetText"/> 
    <xsl:with-param name="pRep" select="$pRep"/> 
    </xsl:call-template> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
</xsl:stylesheet> 

當所提供的XML文檔施加(校正爲良好形成):

<html> 
<h1>This word should not be replaced: TEST</h1>. 
But this one should be replaced: test 
</html> 

產生通緝的結果

<html> 
<h1>This word should not be replaced: TEST</h1>. 
But this one should be replaced: ABC 
</html> 

請注意

  1. 這是一個通用的轉型接受作爲參數來確定目標和替換文本。

  2. 替換是不區分大小寫的,但我們假設目標參數是以小寫形式提供的。

  3. 用XSLT 2.0解決這個問題甚至更容易。

+0

@Scott,爲了在被替換的字符串周圍獲得想要的粗體標籤,用'' pRep「/>'。 – LarsH 2010-11-06 10:14:16

+0

@LarsH:感謝您的觀察。我編輯了這個答案,並提出了兩條建議,以便實現大規模的操作 - 我確實希望儘可能保持處理的通用性。 – 2010-11-06 15:10:06

+0

謝謝,這可以使用原生PHP版本5.x完成,是嗎? – 2010-11-07 02:00:25