XSLT:外部ファイルの内容(リスト)に応じた文字置換
XSLTで、document()関数を使用して外部ファイルへアクセスし、外部ファイルのリストに応じた文字置換が行いたいです。
変換元ファイル:test.xml
<topic> <title>吾輩は猫である。</title> <body> <section> <title>一</title> <p>吾輩は猫である。</p> <p>名前はまだ無い。</p> <p>どこで生れたかとんと見当がつかぬ。</p> <p>何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。</p> <p>吾輩はここで始めて人間というものを見た。</p> </section> </body> </topic>
試したこと
外部ファイルにアクセスせず、ひとつの単語の置換には、下記のXSLTを使用しました。
XSLT:change.xsl
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 《中略》 <xsl:template match="p"> <xsl:variable name="target_tarm" select="'吾輩'"/> <xsl:variable name="replace_tarm" select="'【わたくし】'"/> <xsl:choose> <xsl:when test="contains(./text(),$target_tarm)"> <xsl:variable name="non_change_before"> <xsl:value-of select="substring-before(./text(),$target_tarm)"/> </xsl:variable> <xsl:variable name="non_change_after"> <xsl:value-of select="substring-after(./text(),$target_tarm)"/> </xsl:variable> <p><xsl:value-of select="$non_change_before"/><xsl:value-of select="$replace_tarm"/><xsl:value-of select="$non_change_after"/></p> </xsl:when> <xsl:otherwise> <xsl:copy-of select="."/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
出力01:output01.xml
<topic> <title>吾輩は猫である。</title> <body> <section> <title>一</title> <p>【わたくし】は猫である。</p> <p>名前はまだ無い。</p> <p>どこで生れたかとんと見当がつかぬ。</p> <p>何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。</p> <p>【わたくし】はここで始めて人間というものを見た。</p> </section> </body> </topic>
【わたくし】が置換部分です。
change.xslの以下部分を、外部ファイルのリストに従って処理をさせたいです。
<xsl:variable name="target_tarm" select="'吾輩'"/> <xsl:variable name="change_tarm" select="'【わたくし】'"/>
とりあえず、3つの単語を置換するリストです。
外部ファイル:list.xml
<list> <para> <sequence>00001</sequence> <target>吾輩</target> <replace>【わたくし】</replace> </para> <para> <sequence>00002</sequence> <target>猫</target> <replace>【犬】</replace> </para> <para> <sequence>00003</sequence> <target>人間</target> <replace>【民間人】</replace> </para> </list>
希望する出力:output02.xml
<topic> <title>吾輩は猫である。</title> <body> <section> <title>一</title> <p>【わたくし】は【犬】である。</p> <p>名前はまだ無い。</p> <p>どこで生れたかとんと見当がつかぬ。</p> <p>何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。</p> <p>【わたくし】はここで始めて【民間人】というものを見た。</p> </section> </body> </topic>
次のXSLTで変換をしてみたのですが、1つのmuch=""に対して、外部ファイル内のfor-each分、処理が繰り返されてしまい、残念な結果しか得られませんでした。
XSLT:replace.xsl <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:strip-space elements="*"/> <xsl:output indent="yes"/> <xsl:variable name="tarm_list" select="document('list.xml')"/> 《中略》 <xsl:template match="p"> <xsl:variable name="current_text" select="."/> <xsl:for-each select="$tarm_list//para"> <xsl:variable name="target_tarm" select="./target"/> <xsl:variable name="replace_tarm" select="./replace"/> <xsl:choose> <xsl:when test="contains($current_text,$target_tarm)"> <xsl:variable name="non_change_before"> <xsl:value-of select="substring-before($current_text,$target_tarm)"/> </xsl:variable> <xsl:variable name="non_change_after"> <xsl:value-of select="substring-after($current_text,$target_tarm)"/> </xsl:variable> <p><xsl:value-of select="$non_change_before"/><xsl:value-of select="$replace_tarm"/><xsl:value-of select="$non_change_after"/></p> </xsl:when> <xsl:otherwise> <p> <xsl:value-of select="$current_text"/> </p> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:template> </xsl:stylesheet>
残念な出力:output03.xml
<topic> <title>吾輩は猫である。</title> <body> <section> <title>一</title> <p>【わたくし】は猫である。</p> <p>吾輩は【犬】である。</p> <p>吾輩は猫である。</p> <p>名前はまだ無い。</p> <p>名前はまだ無い。</p> <p>名前はまだ無い。</p> <p>どこで生れたかとんと見当がつかぬ。</p> <p>どこで生れたかとんと見当がつかぬ。</p> <p>どこで生れたかとんと見当がつかぬ。</p> <p>何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。</p> <p>何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。</p> <p>何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。</p> <p>【わたくし】はここで始めて人間というものを見た。</p> <p>吾輩はここで始めて人間というものを見た。</p> <p>吾輩はここで始めて【民間人】というものを見た。</p> </section> </body> </topic>
外部ファイルのリスト項目を1つづつ照らし合わせながら、変換元ファイル(test.xml)を処理させるには、どうすればよろしいでしょうか。XSLTの誤りをご指摘いただけると助かります。
根本的に上記の方法ではNGな場合、別途の方法をご紹介いただけるとなお幸いです。
よろしくご教授のほど、お願いいたします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/04/14 10:58