2010-12-15 73 views
0

J'ai déjà posté la question comment ajouter des balises acronyme au texte HTML et a obtenu une bonne solution (voir Use xslt:analyze-string to add acronyms to HTML). Je vous remercie!Utiliser xslt: analyser-chaîne pour ajouter des acronymes en HTML - maintenant avec des synonymes

Maintenant, j'ai ajouté des synonymes à mes acronymes et adapté la solution - cela fonctionne bien.

Ma seule question: est-il utile de mettre l'instruction xsl: analyze-string pour les synonymes dans la partie xsl: non-matching-substring de la première xsl: analyze-string du mot principal (name)? Existe-t-il d'autres moyens de mettre en œuvre ceci?

Ci-dessous ma source et la transformation.

Merci pour vos conseils! :-)

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> 

Répondre

2

Vous compliquer encore les choses! ;-)

Dimitries excellente solution pourrait facilement être ajustée pour répondre à vos besoins sans introduire un autre xsl:analyze-string.

Tout ce que vous devez faire est de faire une union des @name s et synonym s lorsque vous appelez my:replace-words:

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

Réglez ensuite la fonction my:replace-words en conséquence en supprimant le paramètre synonyms et en utilisant xsl:value-of à xsl:non-matching-substring que vous fait avant.

Remplacez votre fonction actuelle my:insert-acronyms avec:

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

... et votre my:replace-words actuelle avec:

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

En faisant cela, le code XML suivant:

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

Est-ce que le résultat suivant:

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

Salut Per, merci pour la réponse rapide et utile! – Suidu