<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:skos="http://www.w3.org/2004/02/skos/core#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dct="http://purl.org/dc/terms/" xmlns:file="http://expath.org/ns/file" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:isothes="http://purl.org/iso25964/skos-thes#" xmlns:cc="http://creativecommons.org/ns#" xmlns:tei="http://www.tei-c.org/ns/1.0" xmlns:fn="http://www.w3.org/2005/xpath-functions" version="3.0" exclude-result-prefixes="#all"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes"/> <xsl:param name="inputFile" select="unparsed-text('input.json')"/> <xsl:param name="lang" select="'en'"/> <xsl:param name="vocabulary" select="'/home/thouvenin/devel/web-services/loterre-resolvers/v1/QX8.skos'"/> <xsl:variable name="DICO" select="document($vocabulary)/rdf:RDF"/> <!--=============================================================== 0- traitement du thésaurus : création d'un index avec les prefs, les synos et les hiddens triés ========================================================================--> <xsl:variable name="FRE"> <xsl:for-each select="$DICO//skos:Concept/skos:prefLabel[@xml:lang='fr']"> <!--liste d'exclusion--> <xsl:if test="not(.=('SOI', 'SOC', 'climat', 'K', 'B','N,','S','Si','D','Cl','H'))"> <terme> <xsl:attribute name="id"> <xsl:value-of select="../@rdf:about"/> </xsl:attribute> <xsl:attribute name="lang">fr</xsl:attribute> <xsl:attribute name="status">pref</xsl:attribute> <xsl:value-of select="normalize-space(.)"/> </terme> </xsl:if> </xsl:for-each> <xsl:for-each select="$DICO//skos:Concept/skos:altLabel[@xml:lang='fr' and not(contains(.,'?')) and not(.='')] | $DICO//skos:Concept/skos:hiddenLabel[@xml:lang='fr' and not(contains(.,'?')) and not(.='')]"> <!--liste d'exclusion--> <!--liste d'exclusion--> <xsl:if test="not(.=('SOI', 'SOC', 'climat', 'K', 'B','N,','S','Si','D','Cl','H'))"> <terme> <xsl:attribute name="id"> <xsl:value-of select="../@rdf:about"/> </xsl:attribute> <xsl:attribute name="lang">fr</xsl:attribute> <xsl:attribute name="status">syn</xsl:attribute> <xsl:attribute name="renvoi"><xsl:value-of select="../skos:prefLabel[@xml:lang='fr']"/></xsl:attribute> <xsl:value-of select="normalize-space(.)"/> </terme> </xsl:if> </xsl:for-each> </xsl:variable> <xsl:variable name="ENG"> <xsl:for-each select="$DICO//skos:Concept/skos:prefLabel[@xml:lang='en']"> <!--liste d'exclusion--> <xsl:if test="not(.=('SOI', 'SOC', 'climate', 'K', 'B','N,','S','Si','D','Cl','H'))"> <terme> <xsl:attribute name="id"> <xsl:value-of select="../@rdf:about"/> </xsl:attribute> <xsl:attribute name="lang">en</xsl:attribute> <xsl:attribute name="status">pref</xsl:attribute> <xsl:value-of select="normalize-space(.)"/> </terme> </xsl:if> </xsl:for-each> <xsl:for-each select="$DICO//skos:Concept/skos:altLabel[@xml:lang='en' and not(.='')] | $DICO//skos:Concept/skos:hiddenLabel[@xml:lang='en' and not(.='')]"> <!-- liste d'exclusion --> <!--liste d'exclusion--> <xsl:if test="not(.=('SOI', 'SOC', 'climate', 'K', 'B','N,','S','Si','D','Cl','H'))"> <terme> <xsl:attribute name="id"> <xsl:value-of select="../@rdf:about"/> </xsl:attribute> <xsl:attribute name="lang">en</xsl:attribute> <xsl:attribute name="status">syn</xsl:attribute> <xsl:attribute name="renvoi"><xsl:value-of select="../skos:prefLabel[@xml:lang='en']"/></xsl:attribute> <xsl:value-of select="normalize-space(.)"/> </terme> </xsl:if> </xsl:for-each> </xsl:variable> <xsl:variable name="dicoName"> <xsl:for-each select="$DICO//skos:ConceptScheme"> <dico> <xsl:attribute name="uri" select="@rdf:about"/> <xsl:choose> <xsl:when test="dct:title[@xml:lang='fr']"> <xsl:value-of select="dct:title[@xml:lang='fr']"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="dct:title[@xml:lang='en']"/> </xsl:otherwise> </xsl:choose> </dico> </xsl:for-each> </xsl:variable> <!-- ================================================================================================= 1- fichier d'entrée =====================================================================================================--> <xsl:template match="/" name="main"> <xsl:variable name="PASS1"> <pass1> <xsl:copy> <xsl:apply-templates select="@*|node()" mode="input"/> </xsl:copy> </pass1> </xsl:variable> <xsl:apply-templates select="exslt:node-set($PASS1)/pass1"/> </xsl:template> <xsl:template match="@*|node()" mode="input"> <xsl:copy> <xsl:apply-templates select="@*|node()" mode="input"/> </xsl:copy> </xsl:template> <!-- ================================================================================================= 2- annotation de chaque article =====================================================================================================--> <xsl:template match="pass1"> <xsl:variable name="PASS2"> <pass2> <root> <xsl:for-each select="//fn:map[child::fn:string[@key='id']] | //fn:map[child::node()[local-name(.)='id']]"> <record> <xsl:attribute name="id"> <xsl:value-of select="descendant::fn:string[@key='id']"/> </xsl:attribute> <!--<xsl:variable name="id"> <xsl:value-of select="descendant::fn:string[@key='id']"/> </xsl:variable> <xsl:variable name="docLanguage"> <xsl:value-of select="descendant::fn:array[@key='language']/fn:string"/> </xsl:variable> <xsl:variable name="title"> <xsl:value-of select="descendant::fn:string[@key='title']"/> </xsl:variable> <xsl:variable name="abstract"> <xsl:value-of select="descendant::fn:string[@key='abstract']"/> </xsl:variable> <xsl:variable name="nativeKeywords"> <xsl:for-each select="descendant::fn:array[@key='subject']/descendant::fn:string[@key='value']"> <xsl:text> </xsl:text><xsl:value-of select="."/><xsl:text> </xsl:text> </xsl:for-each> </xsl:variable>--> <!--<xsl:variable name="fullText"> <xsl:value-of select="$CORPUS//tei:TEI[descendant::tei:idno=$id]/normalize-space(string-join(descendant-or-self::text(), ' '))"/> </xsl:variable>--> <!-- titre + résumé + MCA --> <!-- <xsl:variable name="TitleAbstractKeywords"> <!-\-<xsl:value-of select="concat(fn:string[@key='title'], fn:string[@key='abstract'], fn:map[@key='keywords'])"/>-\-><!-\- keywords = teeft -\-> <xsl:value-of select="concat(' ',descendant::fn:string[@key='title'], ' ', descendant::fn:string[@key='abstract'], ' ', $nativeKeywords, ' ')"/> </xsl:variable>--> <!-- tous les contenus textuels (même les identifiants !) dans une variable--> <!-- <xsl:variable name="docText" select="normalize-space(string-join(descendant-or-self::text(), ' '))"/>--> <!-- <xsl:variable name="docText" select="normalize-space(string-join(descendant::fn:string[@key='value'], ' '))"/>--> <xsl:variable name="docText" select="normalize-space(string-join(descendant::node()[local-name(.)='value' or @key='value'], ' '))"/> <!-- <xsl:copy-of select="node()"/>--> <!--=====================================Annotation proprement dite================================--> <xsl:for-each select="$dicoName/dico"> <xsl:variable name="uriDico" select="@uri"/> <!-- <array> <xsl:attribute name="key">annotations</xsl:attribute>--> <!-- <xsl:if test="$docLanguage=('fr', 'fre', 'fra', 'FR', 'FRE', 'FRA') ">--> <xsl:if test="$lang=('fr', 'fre', 'fra', 'FR', 'FRE', 'FRA') "> <!-- annotation avec les termes français de la ressource terminologique dont l'uri correspond à $uriDico--> <xsl:for-each select="$FRE/terme[substring-before(@id, '-')=$uriDico]"> <xsl:variable name="keyword" select="."/> <xsl:variable name="id" select="@id"/> <xsl:variable name="status" select="@status"/> <xsl:variable name="renvoi" select="@renvoi"/> <!-- word boundary "\W" ne tient pas compte des lettres accentuées ("début" et "d'eau" génèrent "Deutérium" dont l'altLabel est "D"; la variable "nonWordChar" intègre les lettres accentuées (\u00C0 jusqu'à \u017F) et les 3 formes d'apostrophe(\u0027, \u02BC, \u2019)--> <xsl:variable name="nonWordChar" select="'[^0-9A-Za-z\u00C0-\u017F\u0027\u02BC\u2019]'"/> <!-- <xsl:variable name="nonWordChar" select="'[^\\p{L}+$]'"/>--> <!-- variable keyword2 : intègre les word boundaries pour ne prendre que les termes entiers ; échappe les caractères RegExp réservés--> <xsl:variable name="keyword2" select="concat($nonWordChar, replace(replace(replace(replace(replace(replace(replace(replace(replace($keyword, ',',','), '+', '\\+' , '!iq'), '(','\\(', '!iq'), ')', '\\)','!iq'), '[', '\\[' , '!iq'), ']', '\\]' , '!iq'), '{', '\\{' , '!iq'), '}', '\\}' , '!iq'), '|', '\\|' , '!iq'),$nonWordChar)"/> <xsl:analyze-string select="concat('\W',$docText,'\W')" regex="{$keyword2}" flags="!i" > <!-- <xsl:analyze-string select="concat('\W',$TitleAbstractKeywords,'\W')" regex="{$keyword2}" flags="!i" >--> <!-- <xsl:analyze-string select="concat('\W',$fullText,'\W')" regex="{$keyword2}" flags="!i" >--> <xsl:matching-substring> <annotation> <lang>fre</lang> <prefLabel> <!--on ne sort que le préférentiel--> <xsl:choose> <xsl:when test="$status='pref'"> <xsl:value-of select="$keyword"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$renvoi"/> </xsl:otherwise> </xsl:choose> </prefLabel> <termeReconnu> <xsl:value-of select="."/> </termeReconnu> <conceptUri> <xsl:value-of select="$id"/> </conceptUri> <status> <xsl:value-of select="$status"/> </status> <renvoi> <xsl:value-of select="$renvoi"/> </renvoi> </annotation> </xsl:matching-substring> <xsl:non-matching-substring> <!-- on ne sort pas le reste du texte pour alléger le résultat--> </xsl:non-matching-substring> </xsl:analyze-string> </xsl:for-each> </xsl:if> <xsl:if test="$lang=('en', 'eng','EN','ENG','de','ger','dut','unknown')"> <!-- annotation avec les termes anglais de la ressource terminologique --> <xsl:for-each select="$ENG/terme[substring-before(@id, '-')=$uriDico]"> <xsl:variable name="keyword" select="."/> <xsl:variable name="id" select="@id"/> <xsl:variable name="status" select="@status"/> <xsl:variable name="renvoi" select="@renvoi"/> <!-- variable keyword2 : intègre les word boundaries pour ne prendre que les termes entiers ; échappe les caractères RegExp réservés--> <xsl:variable name="keyword2" select="concat('\W', replace(replace(replace(replace(replace(replace(replace(replace(replace(replace($keyword, ',',','), '+', '\\+' , '!iq'), '(','\\(', '!iq'), ')', '\\)','!iq'), '[', '\\[' , '!iq'), ']', '\\]' , '!iq'), '{', '\\{' , '!iq'), '}', '\\}' , '!iq'), '|', '\\|' , '!iq'), '-', '\\‐' , '!iq'),'\W')"/> <xsl:analyze-string select="concat('\W',$docText,'\W')" regex="{$keyword2}" flags="!i" > <!-- <xsl:analyze-string select="concat('\W',$TitleAbstractKeywords,'\W')" regex="{$keyword2}" flags="!i" >--> <!-- <xsl:analyze-string select="concat('\W',$fullText,'\W')" regex="{$keyword2}" flags="!i" >--> <xsl:matching-substring> <annotation> <lang>eng</lang> <prefLabel> <!--on ne sort que le préférentiel--> <xsl:choose> <xsl:when test="$status='pref'"> <xsl:value-of select="$keyword"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$renvoi"/> </xsl:otherwise> </xsl:choose> </prefLabel> <termeReconnu> <xsl:value-of select="."/> </termeReconnu> <conceptUri> <xsl:value-of select="$id"/> </conceptUri> <status> <xsl:value-of select="$status"/> </status> <renvoi> <xsl:value-of select="$renvoi"/> </renvoi> </annotation> </xsl:matching-substring> <xsl:non-matching-substring> <!-- on ne sort pas le reste du texte pour alléger le résultat--> </xsl:non-matching-substring> </xsl:analyze-string> </xsl:for-each> </xsl:if> </xsl:for-each> </record> </xsl:for-each> </root> </pass2> </xsl:variable> <xsl:apply-templates select="exslt:node-set($PASS2)/pass2"/> </xsl:template> <!-- =================================================================== 3- regroupement des annotations par vocabulaire puis par terme ======================================================================= --> <xsl:template match="pass2"> <root> <xsl:for-each select="//record"> <!-- début de chaque document --> <record> <xsl:copy-of select="@id" copy-namespaces="0"/> <!-- on regroupe les annotations et on factorise sur l'identifiant ark (scheme) et sur le terme--> <!-- <xsl:for-each-group select="descendant::fn:map[parent::fn:array[@key='annotations']]" group-by="fn:string[@key='conceptUri'], fn:array[@key='lang']/fn:string" composite="1">--> <!-- on regroupe les annotations et on factorise sur le terme + langue--> <xsl:for-each-group select="descendant::annotation" group-by="prefLabel, lang" composite="1"> <xsl:variable name="freq" select="count(current-group()) "/> <annotation> <lang> <xsl:value-of select="current-grouping-key()[2]"/> </lang> <prefLabel><xsl:value-of select="current-grouping-key()[1]"/></prefLabel> <xsl:for-each-group select="current-group()/termeReconnu" group-by="."> <termeReconnu> <xsl:value-of select="current-grouping-key()"/> </termeReconnu> </xsl:for-each-group> <!--Termes génériques--> <xsl:for-each-group select="current-group()/conceptUri" group-by="."> <!-- tous les génériques de niveau 1 du concept --> <xsl:for-each select="$DICO//skos:Concept[@rdf:about=current-grouping-key()]/skos:broader"> <xsl:variable name="génériques"> <xsl:call-template name="classif"> <xsl:with-param name="tg" select="@rdf:resource"/> <xsl:with-param name="position">1</xsl:with-param> </xsl:call-template> </xsl:variable> <!-- génériques dans une variable pour pouvroir les renuméroter dans le sens décroissant--> <xsl:variable name="génériques_num"> <xsl:for-each select="$génériques//tg[starts-with(.,'1')]"> <xsl:variable name="position">1</xsl:variable> <xsl:variable name="string1" select="."/> <xsl:choose> <xsl:when test="following::node()[starts-with(name(.), 'TG_')]"> <xsl:for-each select="following::node()[starts-with(name(.), 'TG_') and not(child::node()[starts-with(name(.), 'TG_')])]"> <xsl:variable name="niveau" select="number(substring-after(name(.), 'TG_'))"/> <xsl:variable name="num">1</xsl:variable> <arbreHierarchique> <tg> <xsl:value-of select="tg"/> </tg> <xsl:call-template name="previousTG"> <xsl:with-param name="tg" select="parent::node()[starts-with(name(.), 'TG_')][last()]/tg"/> <xsl:with-param name="niveau" select="$niveau -1"/> <xsl:with-param name="num" select="$num +1"/> </xsl:call-template> <tg> <xsl:value-of select="$string1"/> </tg> </arbreHierarchique> </xsl:for-each> </xsl:when> <xsl:otherwise> <arbreHierarchique> <tg xsl:exclude-result-prefixes="#all"> <xsl:value-of select="$string1"/> </tg> </arbreHierarchique> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:variable> <!-- renumérotation --> <xsl:variable name="génériques_Renum"> <xsl:for-each select="$génériques_num/arbreHierarchique"> <arbreHierarchique> <xsl:for-each select="tg"> <tg> <xsl:value-of select="concat(position(), ' - ',substring(.,3))"/> </tg> </xsl:for-each> </arbreHierarchique> </xsl:for-each> </xsl:variable> <!-- regroupement sur une ligne --> <xsl:for-each select="$génériques_Renum/arbreHierarchique"> <arbreHierarchique> <xsl:for-each select="tg"> <xsl:choose> <xsl:when test="position()=last()"> <xsl:value-of select="."/> </xsl:when> <xsl:otherwise> <xsl:value-of select="."/> <xsl:text>, </xsl:text> </xsl:otherwise> </xsl:choose> </xsl:for-each> </arbreHierarchique> </xsl:for-each> </xsl:for-each> <conceptUri> <xsl:value-of select="current-grouping-key()"/> </conceptUri> </xsl:for-each-group> <outil>Loterre_Annot</outil> <frequence> <xsl:value-of select="$freq "/> </frequence> </annotation> </xsl:for-each-group> </record> </xsl:for-each> </root> </xsl:template> <!-- =================================================================== TG ======================================================================= --> <xsl:template name="classif"> <xsl:param name="tg"/> <xsl:param name="position"/> <xsl:if test="$DICO//skos:Concept[@rdf:about=$tg]"> <tg> <xsl:value-of select="concat($position, '-',$DICO//skos:Concept[@rdf:about=$tg]/skos:prefLabel[@xml:lang='en'])"/> </tg> <xsl:for-each select="$DICO//skos:Concept[@rdf:about=$tg]/skos:broader/@rdf:resource"> <xsl:element name="{concat('TG_',$position +1)}"> <xsl:call-template name="classif99"> <xsl:with-param name="tg" select="."/> <xsl:with-param name="position"> <xsl:value-of select="$position +1"/> </xsl:with-param> </xsl:call-template> </xsl:element> </xsl:for-each> <!--</xsl:otherwise> </xsl:choose>--> </xsl:if> </xsl:template> <!-- =================================================================== TG99 ======================================================================= --> <xsl:template name="classif99"> <xsl:param name="tg"/> <xsl:param name="position"/> <xsl:if test="$DICO//skos:Concept[@rdf:about=$tg]"> <tg> <xsl:value-of select="concat($position, '-',$DICO//skos:Concept[@rdf:about=$tg]/skos:prefLabel[@xml:lang='en'])"/> </tg> <xsl:for-each select="$DICO//skos:Concept[@rdf:about=$tg]/skos:broader/@rdf:resource"> <xsl:element name="{concat('TG_',$position+1)}"> <xsl:call-template name="classif99"> <xsl:with-param name="tg" select="."/> <xsl:with-param name="position"> <xsl:value-of select="$position +1"/> </xsl:with-param> </xsl:call-template> </xsl:element> </xsl:for-each> </xsl:if> </xsl:template> <!-- =================================================================== TG précédant ======================================================================= --> <xsl:template name="previousTG"> <xsl:param name="tg"/> <xsl:param name="niveau"/> <xsl:param name="num"/> <xsl:for-each select="parent::node()[starts-with(name(.), 'TG_') and child::tg=$tg]"> <tg> <xsl:value-of select="$tg"/> </tg> <xsl:call-template name="previousTG"> <!--<xsl:with-param name="tg" select="parent::fn:array[child::fn:array/fn:string=$tg]"/>--> <xsl:with-param name="tg" select="parent::node()[starts-with(name(.), 'TG_')][last()]/tg"/> <xsl:with-param name="niveau" select="$niveau -1"/> <xsl:with-param name="num" select="$num -1"/> </xsl:call-template> </xsl:for-each> </xsl:template> </xsl:stylesheet>