使用xslt:analyze-string将缩写词添加到HTML中 - 现在使用同义词

时间:2010-12-15 10:37:36

标签: xml xslt xslt-2.0

我已经发布了如何向HTML文本添加首字母缩略词标签的问题,并得到了一个很好的解决方案(参见Use xslt:analyze-string to add acronyms to HTML)。谢谢!

现在我在我的首字母缩略词中添加了同义词并修改了解决方案 - 它运行正常。

我唯一的问题:将xsl:analyze-string指令放在主要单词(name)的第一个xsl:analyze-string的xsl:non-matching-substring部分内的同义词中是否有用? 还有其他方法可以实现吗?

在我的来源和转型之下。

感谢您的提示! : - )

Suidu

source.xml:

<?xml version="1.0" encoding="UTF-8"?>
<doc>
    <dictionary>

        <acronym name="WWW">
            <synonym>www</synonym>
            <description>The World Wide Web</description>
        </acronym>

        <acronym name="HTML">
            <synonym>html</synonym>
            <description>The HyperText Markup Language</description>
        </acronym>

    </dictionary>

    <div>
        <p>In the <strong>www</strong> you can find a lot of <em>html</em> documents.</p> 
    </div>

</doc> 

transformation.xsl:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my"  exclude-result-prefixes="my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

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

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

<xsl:template match="text()" priority="0.1">
    <xsl:sequence select="my:insert-acronyms(., /*/dictionary/acronym)"/>
</xsl:template>

<xsl:function name="my:insert-acronyms" as="node()*">
    <xsl:param name="text" as="text()"/>
    <xsl:param name="acronyms" as="node()*"/>

    <xsl:sequence select=
         "if($acronyms)
            then my:replace-words($text, $acronyms/@name, $acronyms/synonym)
            else $text
         "/>
</xsl:function>

<xsl:function name="my:replace-words" as="node()*">
    <xsl:param name="text" as="text()" />
    <xsl:param name="names" as="node()*" />
    <xsl:param name="synonyms" as="node()*" />

    <xsl:analyze-string select="$text" 
         regex="{concat('(^|\W)(', string-join($names, '|'), ')(\W|$)')}">
         <xsl:matching-substring>
          <xsl:value-of select="regex-group(1)"/>
          <acronym title="{$names[. eq regex-group(2)]/../description}">
           <xsl:value-of select="regex-group(2)"/>
          </acronym>
          <xsl:value-of select="regex-group(3)"/>
         </xsl:matching-substring>
         <xsl:non-matching-substring>

            <xsl:analyze-string select="." 
                 regex="{concat('(^|\W)(', string-join($synonyms, '|'), ')(\W|$)')}">
                 <xsl:matching-substring>
                  <xsl:value-of select="regex-group(1)"/>
                  <acronym title="{$synonyms[. eq regex-group(2)]/../description}">
                   <xsl:value-of select="regex-group(2)"/>
                  </acronym>
                  <xsl:value-of select="regex-group(3)"/>
                 </xsl:matching-substring>
                 <xsl:non-matching-substring>
                    <xsl:value-of select="."/>
                 </xsl:non-matching-substring>
            </xsl:analyze-string>


         </xsl:non-matching-substring>
    </xsl:analyze-string>
</xsl:function>

<xsl:template match="dictionary"/>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:2)

你又搞复杂了! ; - )

Dimitries优秀的解决方案可以轻松调整,以满足您的需求,而无需引入另一个xsl:analyze-string

当您致电@name时,您需要做的就是synonymmy:replace-words的联合:

my:replace-words($text, ($acronyms/@name|$acronyms/synonym))

然后通过删除参数my:replace-words并使用synonyms中的xsl:value-of来相应地调整函数xsl:non-matching-substring

将当前函数my:insert-acronyms替换为:

  <xsl:function name="my:insert-acronyms" as="node()*">
    <xsl:param name="text" as="text()"/>
    <xsl:param name="acronyms" as="node()*"/>

    <xsl:sequence select="
      if($acronyms) then
        my:replace-words($text, ($acronyms/@name|$acronyms/synonym))
      else 
        $text"/>
  </xsl:function>

...以及您当前的my:replace-words

  <xsl:function name="my:replace-words" as="node()*">
    <xsl:param name="text" as="text()" />
    <xsl:param name="names" as="node()*" />

    <xsl:analyze-string select="$text" 
      regex="{concat('(^|\W)(', string-join($names, '|'), ')(\W|$)')}">
      <xsl:matching-substring>
        <xsl:value-of select="regex-group(1)"/>
        <acronym title="{$names[. eq regex-group(2)]/../description}">
          <xsl:value-of select="regex-group(2)"/>
        </acronym>
        <xsl:value-of select="regex-group(3)"/>
      </xsl:matching-substring>
      <xsl:non-matching-substring>
        <xsl:value-of select="."/>
      </xsl:non-matching-substring>
    </xsl:analyze-string>
  </xsl:function>

通过这样做,以下XML:

<?xml version="1.0" encoding="UTF-8"?>
<doc>
  <dictionary>
    <acronym name="WWW">
      <synonym>www</synonym>
      <description>The World Wide Web</description>
    </acronym>
    <acronym name="HTML">
      <synonym>html</synonym>
      <description>The HyperText Markup Language</description>
    </acronym>
    <acronym name="XSLT">
      <synonym>xslt</synonym>
      <description>Extensible Stylesheet Language Transformations</description>
    </acronym>
  </dictionary>
  <div>
    <p>In the <strong>www</strong> you can xslt find a lot of <em>html</em> documents.</p> 
  </div>
</doc> 

将返回以下结果:

<div>
  <p>In the <strong>
      <acronym title="The World Wide Web">www</acronym>
    </strong> you can <acronym title="Extensible Stylesheet Language Transformations">xslt</acronym> find a lot of <em>
      <acronym title="The HyperText Markup Language">html</acronym>
    </em> documents.</p>
</div>