我有一些我想测试的字符串,看它们是否包含特定的单词。有问题的单词位于查找节点中,如果匹配,则需要标记字符串中的单词。我有一个几乎可以正常使用的脚本,但我想知道我是否使用最佳格式,因为我认为它相当耗费资源,而且不是非常万无一失。
示例xml:
<Main>
<NTUS>
<NTU>match</NTU>
<NTU>test</NTU>
</NTUS>
<Folder id="update">
<about>This content is not in a span so we ignore it completely, even if we would have a match</about>
<Title>
<span class="string simple" lang="en">Some test content containing a single match</span>
</Title>
<Content>
<span class="string complex" lang="en">Also keywords in sub elements should <strong>pass the test</strong>, and match.</span>
</Content>
</Folder>
</Main>
我当前的xslt:
<xsl:param name="units">
<xsl:copy-of select="//NTU"/>
</xsl:param>
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="NTUS"/>
<xsl:template match="text()[ancestor::span]">
<xsl:analyze-string select="." regex="\s+">
<xsl:matching-substring>
<xsl:value-of select="."/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:variable name="theWord" select="."/>
<xsl:choose>
<xsl:when test="$units/*[text()=$theWord]">
<ntu>
<xsl:value-of select="."/>
</ntu>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
结果如下:
<Main>
<Folder id="update">
<about>This content is not in a span so we ignore it completely, even if we would have a match</about>
<Title>
<span class="string simple" lang="en">Some <ntu>test</ntu> content containing a single <ntu>match</ntu></span>
</Title>
<Content>
<span class="string complex" lang="en">Also keywords in sub elements should <strong>pass the <ntu>test</ntu></strong>, and match.</span>
</Content>
</Folder>
</Main>
除了最后一个节点之外几乎没有问题,因为[match]位于句子的末尾,因此没有通过正则表达式。我可以调整它以使其匹配,但它可能变得相当复杂,所以我想知道是否有更好的方法来解决这个问题。
编辑:当你使用逗号分隔列表时似乎存在一个小的不当行为(可能在其他场合也是如此,但我注意到了这一点)......例如跟随xml
<Main>
<NTUS>
<NTU>OPTION1</NTU>
<NTU>OPTION2</NTU>
<NTU>OPTION3</NTU>
<NTU>OPTION4</NTU>
<NTU>OPTION5</NTU>
</NTUS>
<local xml:lang="en">
<span>Test string containing some comma seperarated lookup values: OPTION1, OPTION2, OPTION3, OPTION4, OPTION5</span>
</local>
应用脚本时返回以下内容:
<span>Test string containing some comma seperarated lookup values: <ntu>OPTION1</ntu>, OPTION2, <ntu>OPTION3</ntu>, OPTION4, <ntu>OPTION5</ntu></span>
所以跳过每一秒的比赛。知道是什么导致了这种行为吗?
答案 0 :(得分: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:variable name="vPatterns" select=
"string-join(/*/NTUS/*, '|')"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="span//text()">
<xsl:analyze-string select="." regex=
"(^|(\P{{L}})+)({$vPatterns})($|(\P{{L}})+)">
<xsl:non-matching-substring><xsl:value-of select="."/></xsl:non-matching-substring>
<xsl:matching-substring>
<xsl:value-of select="regex-group(1)"/>
<ntu><xsl:value-of select="regex-group(3)"/></ntu>
<xsl:value-of select="regex-group(4)"/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的XML文档时:
<Main>
<NTUS>
<NTU>match</NTU>
<NTU>test</NTU>
</NTUS>
<Folder id="update">
<about>This content is not in a span so we ignore it completely, even if we would have a match</about>
<Title>
<span class="string simple" lang="en">Some test content containing a single match</span>
</Title>
<Content>
<span class="string complex" lang="en">Also keywords in sub elements should <strong>pass the test</strong>, and match.</span>
</Content>
</Folder>
</Main>
产生了想要的正确结果:
<Main>
<NTUS>
<NTU>match</NTU>
<NTU>test</NTU>
</NTUS>
<Folder id="update">
<about>This content is not in a span so we ignore it completely, even if we would have a match</about>
<Title>
<span class="string simple" lang="en">Some <ntu>test</ntu> content containing a testmatch or a single <ntu>match</ntu></span>
</Title>
<Content>
<span class="string complex" lang="en">Also keywords in sub elements should <strong>pass the <ntu>test</ntu></strong>, and <ntu>match</ntu>.</span>
</Content>
</Folder>
</Main>