【问题标题】:DOM node.textContent parse and replaceDOM node.textContent 解析和替换
【发布时间】:2010-11-05 22:36:43
【问题描述】:

在下面的 foreach 中,我需要解析关键字的 $node.TextContent 并在其周围加上粗体标签。这对 DOM 可行吗?怎么样?

$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? */
    }

echo $dom-&gt;saveHTML 应该产生:

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

【问题讨论】:

标签: php xslt dom xpath


【解决方案1】:

编辑:正如@LarsH 所注意到的,我没有注意替换应为粗体的要求。

有两种简单的方法可以纠正这个问题:

.1。 在转换中替换

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

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

.2。 不只是作为pReplacement 参数的值传递 "ABC" 而是 &lt;b&gt;ABC&lt;/b&gt;

这个 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 解决这个问题更加容易

【讨论】:

  • @Scott,为了在被替换的字符串周围获得你想要的粗体标签,请将 &lt;xsl:value-of select="$pRep"/&gt; 替换为 &lt;b&gt;&lt;xsl:value-of select="$pRep"/&gt;&lt;/b&gt;
  • @LarsH:感谢您的观察。我编辑了答案,提出了两个如何实现加粗的建议——我真的希望尽可能保持处理的通用性。
  • @Scott:AFAIK LibXml 可以从 PHP 中使用。
猜你喜欢
  • 2016-05-10
  • 1970-01-01
  • 2012-04-30
  • 1970-01-01
  • 2010-09-16
  • 2017-03-12
  • 1970-01-01
  • 2016-10-18
  • 1970-01-01
相关资源
最近更新 更多