2

我需要在 xml 中搜索一个单词及其上下文。例如

<line>hello world, my name is farhad and i'm having trouble with xslt</line>

寻找“和”,三个词的上下文:

<line>hello world, my <span class="context">name is farhad <span class="word">and</span> i'm having</span> trouble with xslt</line>

我能怎么做?我写了一些 xslt 来查找单词,但我无法返回 3 个单词来设置跨度。这是我的 xslt:

<xsl:variable name="delimiters">[,.;!?\s"()]+</xsl:variable>

<xsl:template match="/">
    <xsl:apply-templates select="//line"/>
</xsl:template>

<xsl:template match="line">
    <line>
    <xsl:for-each select="tokenize(.,'\s')">
           <xsl:choose>
               <!-- se l'ultimo carattere è di punteggiatura, prendo la sottostringa senza la punteggiatura -->
               <xsl:when test="compare(replace(.,$delimiters,'$1'),'red') = 0">
                    <span class="word">
                        <xsl:value-of select="."/>
                    </span> 
               </xsl:when>
               <xsl:otherwise>
                       <xsl:value-of select="."/>
                        <xsl:choose>
                            <xsl:when test="position()=last()">
                                <xsl:text></xsl:text>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:text> </xsl:text>
                            </xsl:otherwise>
                        </xsl:choose>
               </xsl:otherwise>
           </xsl:choose>
    </xsl:for-each>
    </line><xsl:text>
    </xsl:text>

</xsl:template>

这是一个示例 xml: http: //pastebin.com/eAVM9CDQ

我还必须在前面的标签上搜索上下文,例如:

  <line>hello world,</line>
<line>my name</line>
<line>is farhad </line>
<line>and i'm having</line>
<line>trouble with xslt</line>

所以,寻找“和”,三个词的上下文:

    <line>hello world,</line>
<line>my <span class="context">name</line>
<line>is farhad </line>
<line><span class="word">and</span> i'm having</span></line>
<line>trouble with xslt</line>

有重叠的问题,但现在这不是问题(我想我知道如何管理它)。如何搜索单词及其上下文?非常感谢。

4

1 回答 1

1

它可以使用 XSLT 2.0 和合适的正则表达式来解决:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:param name="pattern" select="'never saw'"/>
<!-- globale Variable (statt Tunnel-Parameter) -->
<xsl:variable name="rex" select="concat(
        '((\w+\W+){0,3})',      (: leading context :)
        '(', $pattern, ')',     (: matched pattern :)
        '((\W+\w+){0,3})'       (: trailing context :)
    )"/>
<xsl:output indent="yes"/>

<xsl:template match="/">
    <xsl:apply-templates select="*" mode="set-context"/>
</xsl:template>

<xsl:template match="*" mode="set-context">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" mode="set-context"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="text()" mode="set-context">
    <xsl:analyze-string select="." regex="{ $rex }">
        <xsl:matching-substring>
            <span class="context">
                <xsl:value-of select="regex-group(1)"/>
                <span class="word">
                    <xsl:value-of select="regex-group(3)"/>
                </span>
                <xsl:value-of select="regex-group(4)"/>
            </span>
        </xsl:matching-substring>
        <xsl:non-matching-substring>
            <xsl:copy-of select="."/>
        </xsl:non-matching-substring>
    </xsl:analyze-string>
</xsl:template>

<xsl:template match="@*|node()"><!-- identity template -->
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

请注意,您想要的重叠树在 XML 中是不可能的。

于 2010-06-05T13:44:34.810 回答