XSLTによって解析された以下のような文字列があります
boy "happy family" filetype:pdf girl
上記の文字列から、"boy" と "girl" という単語だけを除外し、別の文字列を次のように取得する必要があります。
boy girl
これを達成するにはどうすればよいですか?
XSLT 2.0 ではreplace
、正規表現を取る関数があるため、機能するreplace('boy "happy family" filetype:pdf girl', '"[^"]*"|\w+:\w+', '')
はずです。XSLT 1.0 では、XSLT 1.0 プロセッサが同様の拡張機能をサポートしているかどうかを最初に確認します。
これは、 FXSL(XSLT 1.0で記述されている)によって提供されるトークン化と、使用されているxxx:node-set()
XSLT1.0プロセッサによって提供される拡張機能を使用するXSLT1.0ソリューションです。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="ext">
<xsl:import href="strSplit-to-Words.xsl"/>
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:variable name="vwordNodes">
<xsl:call-template name="str-split-to-words">
<xsl:with-param name="pStr" select="/"/>
<xsl:with-param name="pDelimiters"
select="' '"/>
</xsl:call-template>
</xsl:variable>
<xsl:for-each select=
"ext:node-set($vwordNodes)/*
[not(contains(., '"') or contains(.,':'))
and
count(preceding-sibling::*[contains(., '"')]) mod 2 = 0
]">
<xsl:value-of select="concat(., ' ')"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
この変換が次のXMLドキュメント(提供されたテキスト、単一の上部要素にラップされている)に適用される場合:
<t>boy "happy family" filetype:pdf girl</t>
必要な正しい結果が生成されます:
boy girl
次の、よりトリッキーなXMLドキュメントの場合も、同じ正しい出力が生成されます。
<t>boy " very happy family " filetype:pdf girl</t>
XSLT 1.0 の場合、http://exslt.org/regular-expressions
名前空間に置換があります ( http://exslt.org/regexp/functions/replace/index.htmlを参照) が、Martin が指摘したように、プロセッサには拡張機能のサポートが必要です。
<xsl:value-of select="{http://exslt.org/regular-expressions}replace(STRING, '".*"|\w+:\w+', '')"/>
あなたが求めたものを与えます。