2013-05-17 5 views
1

특정 단어가 포함되어 있는지 테스트하고 싶은 일부 문자열이 있습니다. 문제의 단어는 검색 노드에 있고, 일치하는 단어가 있으면 문자열의 단어를 태그해야합니다. 나는 거의 괜찮아 보이는 스크립트를 가지고 있지만, 내가 최상의 포맷을 사용하고 있는지를 알고 싶다. 오히려 자원을 소비한다고 믿기 때문에, 나는 절대적으로 안전하지는 않다., 최선의 접근 방법은 무엇입니까?

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> 

마지막 노드에서 떨어져 거의 확인되면, [일치하는 것으로 ] 문장의 끝에 있으며 따라서 정규식을 통과하지 않습니다. 일치하도록 조정할 수는 있지만 꽤 복잡해질 수 있으므로이 문제를 해결할 수있는 더 나은 방법이 있는지 알고 싶습니다.

는 편집 : 쉼표로 구분 된 목록을 사용할 때 작은 버릇이 될 것 같다 (다른 경우에있을 수 있습니다,하지만 발견이 하나) ... 예를 들면 그래서

는 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

이 변환 : 원하는 정확한 결과가 생성된다

<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> 
이 변환이 제공된 XML 문서에 적용

<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> 

+0

감사합니다. Dimitre, 내 조회 값에 이스케이프해야하는 문자가 포함되어있을 경우를 대비해 약간 조정해야합니다. 그러나 이것이 올바른 방향으로 시작해야합니다. – Wokoman

+0

@Wokoman, 여러분 환영합니다. –

+0

실제로 정규 표현식에 약간의 버그가있는 것 같지만, 그것을 이해할 수는 없습니다. 원래 게시물에 예제를 추가했습니다. 아무런 논리도없는 것처럼 보입니다. – Wokoman

관련 문제