次の HTML ページがある場合
<div>
<p>
Hello world!
</p>
<p> <a href="example.com"> Hello and Hello again this is an example</a></p>
</div>
たとえば「こんにちは」などの特定の単語を取得し、ドキュメント内のどこにいても「ようこそ」に変更したい
何か提案はありますか?使用しているパーサーの種類に関係なく、喜んでお答えいたします。
次の HTML ページがある場合
<div>
<p>
Hello world!
</p>
<p> <a href="example.com"> Hello and Hello again this is an example</a></p>
</div>
たとえば「こんにちは」などの特定の単語を取得し、ドキュメント内のどこにいても「ようこそ」に変更したい
何か提案はありますか?使用しているパーサーの種類に関係なく、喜んでお答えいたします。
これは、XSLT を使用すると簡単に実行できます。
XSLT 1.0 ソリューション:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pTarget" select="'hello'"/>
<xsl:param name="pReplacement" select="'welcome'"/>
<xsl:variable name="vtargetLength" select=
"string-length($pTarget)"/>
<xsl:variable name="vUpper" select=
"'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="vLower" select=
"'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()" name="replace">
<xsl:param name="pText" select="."/>
<xsl:variable name="vLowerText" select=
"translate($pText,$vUpper,$vLower)"/>
<xsl:choose>
<xsl:when test=
"not(contains(concat(' ', $vLowerText, ' '),
concat(' ',$pTarget,' ')
)
)">
<xsl:value-of select="$pText"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="vOffset" select=
"string-length(
substring-before(concat(' ', $vLowerText, ' '),
concat(' ', $pTarget,' ')
)
)"/>
<xsl:value-of select="substring($pText, 1, $vOffset)"/>
<xsl:value-of select="$pReplacement"/>
<xsl:call-template name="replace">
<xsl:with-param name="pText" select=
"substring($pText, $vOffset + $vtargetLength+1)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
この変換が提供された XML ドキュメントに適用される場合:
<div>
<p>
Hello world!
</p>
<p> <a href="example.com"> Hello and Hello again this is an example</a></p>
</div>
必要な正しい結果が生成されます。
<div>
<p>
welcome world!
</p>
<p>
<a href="example.com"> welcome and welcome again this is an example</a>
</p>
</div>
私の推測では、マッチングと置換では大文字と小文字が区別されません (つまり、"hello" と "heLlo" は両方とも "welcome" に置き換える必要があります)。大文字と小文字を区別する一致が必要な場合は、変換を大幅に簡素化できます。
XSLT 2.0 ソリューション:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pTarget" select="'hello'"/>
<xsl:param name="pReplacement" select="'welcome'"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()[matches(.,$pTarget, 'i')]">
<xsl:variable name="vEnlargedRep" select=
"replace(concat(' ',.,' '),
concat(' ',$pTarget,' '),
concat(' ',$pReplacement,' '),
'i')"/>
<xsl:variable name="vLen" select="string-length($vEnlargedRep)"/>
<xsl:sequence select=
"substring($vEnlargedRep,2, $vLen -2)"/>
</xsl:template>
</xsl:stylesheet>
この変換が提供された XML ドキュメント (上に表示) に適用されると、ここでも必要な正しい結果が生成されます。
<div>
<p>
welcome world!
</p>
<p>
<a href="example.com"> welcome and welcome again this is an example</a>
</p>
</div>
説明: 標準の XPath 2.0 関数matches()
を使用replace()
し、3 番目の引数として指定する"i"
-- 大文字と小文字を区別しない操作のフラグ。