- From: RICAUD-DUSSARGET Matthieu <matthieu.ricaud@igs-cp.fr>
- Date: Wed, 19 Feb 2014 09:54:35 +0100
- To: XProc Dev <xproc-dev@w3.org>
- Message-ID: <CADRkOwESb-QR9FmD9dpcV6opeG-=9sqCgtHHd5mGkKtTQFURJA@mail.gmail.com>
Hi Geert, Yes, you're right. Most of our XSLT define serialize options and character-maps, so I had to write this step when I discovered xproc doesn't deal with it :( But on the other hand xproc adapted to our need that I have no regret ;) It's a kind of "hack" waiting for v2 ! Cheers, Matthieu 2014-02-19 8:17 GMT+01:00 Geert J. <geert.josten@dayon.nl>: > Hi Matthieu, > > > > You have been persistent. Almost 600 lines of code for something you would > imagine should be relatively trivial in XProc.. :-/ > > > > Have character-maps been added to v2 reqs yet? > > > > Cheers, > > Geert > > > > *Van:* RICAUD-DUSSARGET Matthieu [mailto:matthieu.ricaud@igs-cp.fr] > *Verzonden:* maandag 17 februari 2014 14:41 > > *Aan:* XProc Dev > *Onderwerp:* Re: p:store serialization "character-map like" > > > > Hi, > > > > We have adapt this igs:xslt step since last time. The main result can be > optionnaly stored according to the xsl:output. > > Sorry this is french commented, I don't have the time to translate. Feel > free to ask if something's not clear. > > > > Hope this helps. > > Cheers > > Matthieu > > > > HERE IT IS : > > > <!--+=========================================================================================+ > > | Step "igs:xslt" > > | > > | Principe : > > | Effectue une transformation XSLT sur le contenu de la source XML > courante, tout en prenant en charge les xsl:result-document. > > | La transformation fait donc un p:store des output port secondaires > (xsl:result-document) avec la bonne sérialisation : > > | - prise en charge des options des xsl:output > > | - prise en charge des xsl:character-maps. > > | Possibilité de prendre également en charge ces options de sérialisation > sur le résultat principal de la transformation (cf. option > "store_main_result_at") > > | > > | Limitations : > > | * xsl:result-document dans une xsl importée (ou incluse) ne seront pas > pris en compte (erreur), seuls ceux de la xslt principales seront pris en > compte (cf. option "resultdoc_no_error_href"). > > | (car nécessité d'adapter la xslt pour passer le @format dans le > p:base-uri qui est la seule information accessible dans les ports > secondaires, pour ce faire il faudrait stoker toutes le xslt importée et > leur faire passer ce traitement et adapter les href des > xsl:import/xsl:include ce qui est bien compliqué) > > | > > | * xsl:character-map : il est impossible de "créer" dynamiquement de > entités. Utilisez donc : > > | <xsl:output-character character=" " string=" "/> plutôt que > <xsl:output-character character=" " string="&#160;"/> > > | ^^OK^^ ^^KO^^ > > | > > | * options : contrairement à "p:xslt", les options "initial-mode", > "template-name", "output-base-uri" et "version" ne sont actuellement pas > possibles. > > | > > | Options : > > | > > | logFileName (facultatif) : Spécifie un nom de fichier pour stocker > "temporairement" le résultat (hors result-document) de la transformation, > par défaut une valeur avec timestamp est utilisée. > > | (Notamment utile quand on passe plusieurs xslt les unes après les autre > et qu'on veut voir le résultat intermédiaire en mode debug) > > | > > | resultdoc_no_error_href (facultatif) : regex permettant de matcher "les > xsl:result-document/@href" qui ne doivent pas générer d'erreur dans les xsl > importées > > | > > | store_main_result_at (facultatif) : Spécifie un nom de fichier pour > stocker le résultat de la transformation principale (xslt "main") avec les > bonnes options de sérialisation (utilisation du xsl:output par défaut, sans > @name). > > | (cela ne serait pas possible dans un p:store classique qui viendrait > après igs:xslt à moins de connaitre exactement les option de sérialisation) > > > +=========================================================================================+--> > > <p:declare-step type="igs:xslt" name="current"> > > <!--input/output ports--> > > <p:input port="source" sequence="true" primary="true"/> > > <p:input port="parameters" kind="parameter" primary="true"/> > > <p:input port="stylesheet"/> > > <p:output port="result" primary="true"/> > > <!--options--> > > <p:option name="logFileName" select="''"/> > > <p:option name="resultdoc_no_error_href" select="''"/> > > <p:option name="store_main_result_at" select="''"/> > > <!--todo : trouver un moyen de passer ces paramètres à p:xslt s'il sont > présent (et donc de ne pas les passer sinon => @use-when ?!! => non évalué > avant run-time)--> > > <!--<p:option name="initial-mode" /> > > <p:option name="template-name" select="''"/> > > <p:option name="output-base-uri"/> > > <p:option name="version"/>--> > > <!--variables--> > > <p:variable name="xml.uri" select="base-uri()"/> > > <p:variable name="xsl.uri" select="base-uri()"><p:pipe port="stylesheet" > step="current"/></p:variable> > > <p:variable name="xsl.name" select="tokenize($xsl.uri,'/')[last()]"/> > > <p:variable name="debug.file.name" select="if ($logFileName='') then > (concat($xsl.name,'_OUT.xml')) else ($logFileName)"/> > > <p:variable name="href_format_sep" select="'___'"/> > > <!--0. GET GLOBAL PARAMS/OPTIONS--> > > <igs:parameters2xml name="params"/> > > <p:sink/> > > <p:group> > > <p:variable name="debug_folder_name" > select="(//param[@name='debug_folder_name']/@value, > 'debug_default')[1]"><p:pipe port="parameters" step="params"/></p:variable> > > <!--<cx:message> > > <p:input port="source"><p:pipe port="source" step="current"/></p:input> > > <p:with-option name="message" select="concat('resultdoc_no_error_href: ', > $resultdoc_no_error_href)"/> > > </cx:message> > > <p:sink/>--> > > <!-- 1. GET_SERIALIZE-OPTIONS (and result-doc information) --> > > <p:xslt name="get_serialize-options"> > > <p:input port="source"><p:pipe port="stylesheet" step="current"/></p:input> > > <p:with-param name="resultdoc_no_error_href" > select="$resultdoc_no_error_href"/> > > <p:input port="stylesheet"> > > <p:inline> > > <xsl:stylesheet version="2.0" > > xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > > xmlns:xs="http://www.w3.org/2001/XMLSchema" > > xmlns:igs="http://www.igs-cp.fr" > > xmlns:xslt="http://www.w3.org/1999/XSL/Transform" > > > > > <!--<xsl:import href=" > http://localhost:777/neodev.trunk/XSL_LIBS/igs/common.xsl"/>--> > > <xsl:param name="resultdoc_no_error_href"/> > > <xsl:template match="/"> > > <igs:serialize> > > <xsl:apply-templates mode="make_output_for_xproc_serialization"/> > > </igs:serialize> > > </xsl:template> > > <xsl:template match="xsl:stylesheet" > mode="make_output_for_xproc_serialization"> > > <xsl:param name="type" select="'main'" tunnel="yes"/> > > <xsl:variable name="xsl.uri" select="document-uri(/)"/> > > <xsl:variable name="xsl.name" > select="tokenize(string($xsl.uri),'/')[last()]"/> > > <igs:xslt name="{$xsl.name}" type="{$type}"> > > <xsl:copy-of select="namespace::node()"/> > > <xsl:if test="count(xslt:character-map|xslt:output)!=0"> > > <igs:serialize-options> > > <xsl:for-each select="xslt:character-map|xslt:output"> > > <xsl:copy-of select="." copy-namespaces="no"/> > > </xsl:for-each> > > </igs:serialize-options> > > </xsl:if> > > <xsl:if test="count(//xslt:result-document)!=0"> > > <igs:result-documents> > > <xsl:for-each select="//xslt:result-document"> > > <xsl:variable name="error.msg">[ERROR]: xsl:result-document > href="<xsl:value-of select="@href"/>" dans "<xsl:value-of select="$ > xsl.name"/>" (<xsl:value-of select="$type"/>)</xsl:variable> > > <!--<xsl:message>$resultdoc_no_error_href=<xsl:value-of > select="$resultdoc_no_error_href"/>, @href=<xsl:value-of select="@href"/>, > matches=<xsl:value-of > select="matches(@href,$resultdoc_no_error_href)"/></xsl:message>--> > > <xsl:if test="$type!='main'"> > > <xsl:choose> > > <xsl:when test="$resultdoc_no_error_href=''"><xsl:message terminate="yes" > select="$error.msg"/></xsl:when> > > <xsl:when test="matches(@href,$resultdoc_no_error_href)"/> > > <xsl:otherwise><xsl:message terminate="yes" > select="$error.msg"/></xsl:otherwise> > > </xsl:choose> > > </xsl:if> > > <xsl:copy copy-namespaces="no"> > > <xsl:copy-of select="@*"/> > > </xsl:copy> > > </xsl:for-each> > > </igs:result-documents> > > </xsl:if> > > <xsl:apply-templates select="xsl:import|xsl:include" > mode="make_output_for_xproc_serialization"/> > > </igs:xslt> > > </xsl:template> > > <xsl:template match="xsl:import|xsl:include" > mode="make_output_for_xproc_serialization"> > > <xsl:apply-templates select="document(@href)/xsl:stylesheet" > mode="make_output_for_xproc_serialization"> > > <xsl:with-param name="type" select="local-name()" tunnel="yes"/> > > </xsl:apply-templates> > > </xsl:template> > > </xsl:stylesheet> > > </p:inline> > > </p:input> > > </p:xslt> > > <p:choose> > > <p:when test="count(//xsl:output[@name]|//xsl:result-document)!=0"> > > <igs:logFile><p:with-option name="href" > select="resolve-uri(concat($debug_folder_name,'/_',$xsl.name > ,'_get_serialize-options.xml'),$xml.uri)"/></igs:logFile> > > <p:sink/> > > </p:when> > > <p:otherwise><p:sink/></p:otherwise> > > </p:choose> > > <!-- 2. ADD_FORMAT_TO_HREF_RESULTDOC --> > > <!--Ici l'astuce consiste modifier les xsl:result-document/@href pour y > mettre le @format. On pourra ensuite récupérer le @format en parsant le > p:base-uri() qui est la seul info accessible dans les secondary output--> > > <p:choose name="add_format_to_href_resultdoc"> > > <p:xpath-context><p:pipe port="result" > step="get_serialize-options"/></p:xpath-context> > > <!--fixme : attention les result-doc pourraient se trouver dans une xsl > importée--> > > <p:when test="count(//xsl:result-document[@format])!=0"> > > <p:output port="result"><p:pipe port="result" > step="label_element"/></p:output> > > <p:label-elements match="xsl:result-document[@format]" attribute="href" > name="label_element"> > > <!--concat(@href,$href_format_sep,@format)--> > > <p:with-option name="label" select="concat('concat(@href,"', > $href_format_sep ,'",@format)')"/> > > <p:input port="source"><p:pipe port="stylesheet" step="current"/></p:input> > > </p:label-elements> > > <igs:logFile><p:with-option name="href" > select="resolve-uri(concat($debug_folder_name,'/_',$xsl.name > ,'_format_added.xsl'),$xml.uri)"/></igs:logFile> > > <p:sink/> > > </p:when> > > <p:otherwise> > > <p:output port="result"><p:pipe port="result" step="identity"/></p:output> > > <p:identity name="identity"><p:input port="source"><p:pipe > port="stylesheet" step="current"/></p:input></p:identity> > > </p:otherwise> > > </p:choose> > > <p:sink/> > > <!-- 3. PROCESS TRANSFORMATION --> > > <p:group name="transform"> > > <p:output port="result"><p:pipe port="result" step="main_xslt"/></p:output> > > <p:output port="secondary" primary="false" sequence="true"><p:pipe > port="result" step="adapt_secondary"/></p:output> > > <p:variable name="xml_parameters" > select="saxon:serialize(/*,'xml')"><p:pipe port="parameters" > step="params"/></p:variable> > > <p:xslt name="main_xslt"> > > <p:input port="source"><p:pipe port="source" step="current"/></p:input> > > <p:input port="stylesheet"><p:pipe port="result" > step="add_format_to_href_resultdoc"/></p:input> > > <p:with-param name="config" select="$xml_parameters"/> > > <!--<p:with-option name="template-name" select="$template-name" > use-when="$template-name!=''"/>--> > > <!--<p:with-option name="template-name" select="$template-name" > use-when="p:value-available('method')"/>--> > > </p:xslt> > > <p:sink/> > > <!--Si l'option store_main_result_at est définie, on va ajouter > "manuellement" le resultat de la xsl main dans les output port secondaire, > de manière à lui appliquer le même traitement de sérialisation > > (cela évite de refaire tout ce traitement à part). Sinon on conserve le > même port secondaire --> > > <p:choose name="adapt_secondary"> > > <p:when test="$store_main_result_at!=''"> > > <p:output port="result" sequence="true"><p:pipe port="result" > step="secondary_and_main"/></p:output> > > <!--on ajoute le résultat principal (main) de la xslt au résultats > secondaire (result-doc) car on va appliquer le même traitement (ou > presque)--> > > <p:pack wrapper="seq"> > > <p:input port="source"><p:pipe port="secondary" > step="main_xslt"/></p:input> > > <p:input port="alternate"><p:pipe port="result" > step="main_xslt"/></p:input> > > </p:pack> > > <p:identity name="secondary_and_main"> > > <p:input port="source" select="/seq/*"/> > > </p:identity> > > </p:when> > > <p:otherwise> > > <p:output port="result" sequence="true"><p:pipe port="result" > step="secondary_only"/></p:output> > > <p:identity name="secondary_only"> > > <p:input port="source"><p:pipe port="secondary" > step="main_xslt"></p:pipe></p:input> > > </p:identity> > > </p:otherwise> > > </p:choose> > > <p:sink/> > > </p:group> > > <!-- 4. STORE EACH XSL:RESULT-DOC --> > > <p:for-each name="store_resultdoc_with_serialization"> > > <p:iteration-source><p:pipe step="transform" > port="secondary"/></p:iteration-source> > > <p:variable name="resultdoc.serialized_uri" select="p:base-uri()"/> > > <p:variable name="resultdoc.uri" > select="replace($resultdoc.serialized_uri,'___.*$','')"/> > > <p:variable name="resultdoc.format" > select="replace($resultdoc.serialized_uri,'^.*___','')"/> > > <p:variable name="is_main" select="$resultdoc.serialized_uri=$xml.uri"/> > <!--la sortie directe de la xslt main à le même base-uri que le xml > d'entrée--> > > <p:variable name="store.href" select="if($is_main='true') > then($store_main_result_at) else($resultdoc.uri)"/> > > <!--<p:variable name="resultdoc.uri" > select="replace($resultdoc.serialized_uri,concat($href_format_sep,'.*$'),'')"/> > > <p:variable name="resultdoc.format" > select="replace($resultdoc.serialized_uri,concat('^.*',$href_format_sep),'')"/>--> > > <!--<cx:message><p:with-option name="message" select="concat( > > 'xml.uri : ',$xml.uri,' ', > > 'resultdoc.serialized_uri : ',$resultdoc.serialized_uri,' ', > > 'resultdoc.uri : ',$resultdoc.uri,' ', > > 'resultdoc.format : ',$resultdoc.format,' ', > > 'store.href: ',$store.href,' ' > > )"/> > > </cx:message>--> > > <p:choose> > > <p:xpath-context><p:pipe port="result" > step="get_serialize-options"/></p:xpath-context> > > <p:when test="exists(//xsl:output[@name=$resultdoc.format]) or > exists(//xsl:output[not(@name)])"> > > <!--Il existe un output avec le bon format, ou bien un output générique > dans la xsl--> > > <!--xsl:output attributes : byte-order-mark, cdata-section-elements, > doctype-public, doctype-system, encoding, escape-uri-attributes, > include-content-type, indent, media-type, method, name, normalization-form, > omit-xml-declaration, standalone, undeclare-prefixes, use-character-maps, > version--> > > <!--p:store options : les même sauf @name et @use-character-maps--> > > <!--cf. http://www.w3.org/TR/xslt20/#serialization pour les valeurs par > défaut : --> > > <p:variable name="serialize.method" > select="((//xsl:output[@name=$resultdoc.format], > //xsl:output[not(@name)])[1]/@method,'xml')[1]"><p:pipe port="result" > step="get_serialize-options"/></p:variable> > > <p:variable name="serialize.encoding" > select="((//xsl:output[@name=$resultdoc.format], > //xsl:output[not(@name)])[1]/@encoding,'UTF-8')[1]"><p:pipe port="result" > step="get_serialize-options"/></p:variable> > > <p:variable name="serialize.byte-order-mark" > select="((//xsl:output[@name=$resultdoc.format], > //xsl:output[not(@name)])[1]/@byte-order-mark,'yes')[1]"><p:pipe > port="result" step="get_serialize-options"/></p:variable> > > <p:variable name="serialize.cdata-section-elements" > select="((//xsl:output[@name=$resultdoc.format], > //xsl:output[not(@name)])[1]/@cdata-section-elements,'')[1]"><p:pipe > port="result" step="get_serialize-options"/></p:variable> > > <p:variable name="serialize.doctype-system" > select="(//xsl:output[@name=$resultdoc.format], > //xsl:output[not(@name)])[1]/@doctype-system"><p:pipe port="result" > step="get_serialize-options"/></p:variable> > > <p:variable name="serialize.doctype-public" > select="(//xsl:output[@name=$resultdoc.format], > //xsl:output[not(@name)])[1]/@doctype-public"><p:pipe port="result" > step="get_serialize-options"/></p:variable> > > <p:variable name="serialize.escape-uri-attributes" > select="((//xsl:output[@name=$resultdoc.format], > //xsl:output[not(@escape-uri-attributes)])[1]/@method,'yes')[1]"><p:pipe > port="result" step="get_serialize-options"/></p:variable> > > <p:variable name="serialize.include-content-type" > select="((//xsl:output[@name=$resultdoc.format], > //xsl:output[not(@name)])[1]/@include-content-type,'yes')[1]"><p:pipe > port="result" step="get_serialize-options"/></p:variable> > > <p:variable name="serialize.indent" > select="((//xsl:output[@name=$resultdoc.format], > //xsl:output[not(@name)])[1]/@indent,if ($serialize.method='xhtml' or > $serialize.method='html') then ('yes') else ('no'))[1]"><p:pipe > port="result" step="get_serialize-options"/></p:variable> > > <p:variable name="serialize.media-type" > select="((//xsl:output[@name=$resultdoc.format], > //xsl:output[not(@name)])[1]/@media-type, if ($serialize.method='xml') then > ('text/xml') else ( if ($serialize.method='xhtml' or > $serialize.method='html') then ('text/html') else ( if > ($serialize.method='text') then ('text/plain') else ('')) ) )[1]"><p:pipe > port="result" step="get_serialize-options"/></p:variable> > > <p:variable name="serialize.normalization-form" > select="((//xsl:output[@name=$resultdoc.format], > //xsl:output[not(@name)])[1]/@normalization-form,'none')[1]"><p:pipe > port="result" step="get_serialize-options"/></p:variable> > > <p:variable name="serialize.omit-xml-declaration" > select="((//xsl:output[@name=$resultdoc.format], > //xsl:output[not(@name)])[1]/@omit-xml-declaration,'no')[1]"><p:pipe > port="result" step="get_serialize-options"/></p:variable> > > <p:variable name="serialize.standalone" > select="((//xsl:output[@name=$resultdoc.format], > //xsl:output[not(@name)])[1]/@standalone,'omit')[1]"><p:pipe port="result" > step="get_serialize-options"/></p:variable> > > <p:variable name="serialize.undeclare-prefixes" > select="((//xsl:output[@name=$resultdoc.format], > //xsl:output[not(@name)])[1]/@undeclare-prefixes,'')[1]"><p:pipe > port="result" step="get_serialize-options"/></p:variable> > > <p:variable name="serialize.version" > select="((//xsl:output[@name=$resultdoc.format], > //xsl:output[not(@name)])[1]/@version,'1.0')[1]"><p:pipe port="result" > step="get_serialize-options"/></p:variable> > > <p:variable name="serialize.use-character-maps" > select="(//xsl:output[@name=$resultdoc.format], > //xsl:output[not(@name)])[1]/@use-character-maps"><p:pipe port="result" > step="get_serialize-options"/></p:variable> > > <!--<cx:message> > > <p:with-option name="message" select=" concat( > > 'Il existe un output avec le bon format, ou bien un output générique dans > la xsl', ' ', > > '$serialize.method=',$serialize.method, ' ', > > '$serialize.encoding=',$serialize.encoding, ' ', > > '$serialize.byte-order-mark=',$serialize.byte-order-mark, ' ', > > '$serialize.cdata-section-elements=',$serialize.cdata-section-elements, > ' ', > > '$serialize.doctype-system=',$serialize.doctype-system, ' ', > > '$serialize.doctype-public=',$serialize.doctype-public, ' ', > > '$serialize.escape-uri-attributes=',$serialize.escape-uri-attributes, > ' ', > > '$serialize.include-content-type=',$serialize.include-content-type, > ' ', > > '$serialize.indent=',$serialize.indent, ' ', > > '$serialize.media-type=',$serialize.media-type, ' ', > > '$serialize.normalization-form=',$serialize.normalization-form, ' ', > > '$serialize.omit-xml-declaration=',$serialize.omit-xml-declaration, > ' ', > > '$serialize.standalone=',$serialize.standalone, ' ', > > '$serialize.undeclare-prefixes=',$serialize.undeclare-prefixes, ' ', > > '$serialize.version=',$serialize.version, ' ' > > )"/> > > </cx:message>--> > > <p:choose> > > <p:when test="$serialize.use-character-maps!=''"> > > <!--On insert les serialize-option dans le xml (il sera supprimé par > make_character-maps_xslt) --> > > <!--<p:insert match="/*" position="first-child"> > > <p:input port="insertion"><p:pipe port="result" > step="get_serialize-options"/></p:input> > > </p:insert>--> > > <!--plutôt qu'un p:insert on va faire un p:pack, comme ça la racine > (igs:aggregate) aura un namespace connu, ce qui évitera un warning de saxon > : > > WARNING: err:SXXP0005:The source document is in no namespace, but the > template rules all expect elements in a namespace--> > > <p:pack wrapper="igs:aggregate"> > > <p:input port="alternate"><p:pipe port="result" > step="get_serialize-options"/></p:input> > > </p:pack> > > <p:xslt name="make_character-maps_xslt"> > > <p:input port="stylesheet"> > > <p:inline> > > <xsl:stylesheet version="2.0" > > xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > > xmlns:xs="http://www.w3.org/2001/XMLSchema" > > xmlns:igs="http://www.igs-cp.fr" > > xmlns:saxon="http://saxon.sf.net/" > > exclude-result-prefixes="#all" > > > > > <xsl:param name="use-character-maps" required="yes"/> > > <xsl:variable name="character-map" > select="//xsl:character-map[@name=$use-character-maps][1]" > as="element(xsl:character-map)?"/> > > <!--on peut très bien définir le même character-map dans une xsl importée > (donc ici on prend le 1er car "à priori" car ça correspond à l'ordre de > précédence... cf. test unitaire avec saxon)--> > > <xsl:template match="/"> > > <xsl:choose> > > <xsl:when test="count($character-map)=0"> > > <xsl:message terminate="yes">[ERROR] <xsl:value-of > select="count($character-map)"/> character-maps found instead of exactly > one (use-character-maps="<xsl:value-of > select="$use-character-maps"/>").</xsl:message> > > </xsl:when> > > <xsl:otherwise> > > <xsl:next-match/> > > </xsl:otherwise> > > </xsl:choose> > > </xsl:template> > > <!--suppression de la racine créé ci-dessus par la p:pack (évite warning > saxon)--> > > <xsl:template match="igs:aggregate"> > > <xsl:apply-templates/> > > </xsl:template> > > <!--default copy--> > > <xsl:template match="* | @* | processing-instruction() | comment()"> > > <xsl:copy copy-namespaces="no"> > > <xsl:apply-templates select="node()|@*"/> > > </xsl:copy> > > </xsl:template> > > <!-- delete igs:serialize-options which was add on last step so we can > access it within the same file --> > > <xsl:template match="igs:serialize"/> > > <!--text replace according to the matching character-map--> > > <xsl:template match="text()"> > > <xsl:call-template name="replace_character"> > > <xsl:with-param name="text" select="." as="xs:string"/> > > <xsl:with-param name="character-map" select="$character-map" > as="element(xsl:character-map)"/> > > </xsl:call-template> > > </xsl:template> > > <xsl:template name="replace_character"> > > <xsl:param name="text" as="xs:string"/> > > <xsl:param name="character-map" as="element(xsl:character-map)"/> > > <xsl:param name="pos" select="1" as="xs:integer"/> > > <xsl:choose> > > <xsl:when test="$pos le count($character-map/xsl:output-character)"> > > <xsl:variable name="output-character" > select="$character-map/xsl:output-character[$pos]" > as="element(xsl:output-character)"/> > > <xsl:variable name="character" select="$output-character/@character"/> > > <xsl:variable name="string" select="$output-character/@string"/> > > <xsl:call-template name="replace_character"> > > <xsl:with-param name="text" as="xs:string"> > > <xsl:choose> > > <xsl:when test="matches($string,'&(.*?);')"> > > <xsl:message terminate="yes">[ERROR][xsl:character-maps > name="<xsl:value-of select="$character-map/@name"/>", xsl:output-character > character="<xsl:value-of select="$character"/>" string="<xsl:value-of > select="$string"/>"] the string attributes tries to make a new entity which > has to be escaped : this will not be possible, sorry !</xsl:message> > > </xsl:when> > > <xsl:otherwise><xsl:value-of > select="replace($text,$character,$string)"/></xsl:otherwise> > > </xsl:choose> > > </xsl:with-param> > > <xsl:with-param name="character-map" select="$character-map" > as="element(xsl:character-map)"/> > > <xsl:with-param name="pos" select="$pos + 1" as="xs:integer"/> > > </xsl:call-template> > > </xsl:when> > > <xsl:otherwise> > > <xsl:value-of select="$text"/> > > </xsl:otherwise> > > </xsl:choose> > > </xsl:template> > > </xsl:stylesheet> > > </p:inline> > > </p:input> > > <p:with-param name="use-character-maps" > select="$serialize.use-character-maps"/> > > </p:xslt> > > </p:when> > > <p:otherwise><p:identity/></p:otherwise> > > </p:choose> > > <p:store> > > <p:with-option name="method" select="$serialize.method"/> > > <p:with-option name="encoding" select="$serialize.encoding"/> > > <p:with-option name="byte-order-mark" select="if > ($serialize.byte-order-mark='yes') then (1) else (0)"/> > > <p:with-option name="cdata-section-elements" > select="$serialize.cdata-section-elements"/> > > <p:with-option name="doctype-system" select="$serialize.doctype-system"/> > > <p:with-option name="doctype-public" select="$serialize.doctype-public"/> > > <p:with-option name="escape-uri-attributes" select="if > ($serialize.escape-uri-attributes='yes') then (1) else (0)"/> > > <p:with-option name="include-content-type" select="if > ($serialize.include-content-type='yes') then (1) else (0)"/> > > <p:with-option name="indent" select="if ($serialize.indent='yes') then (1) > else (0)"/> > > <p:with-option name="media-type" select="$serialize.media-type"/> > > <p:with-option name="normalization-form" > select="$serialize.normalization-form"/> > > <p:with-option name="omit-xml-declaration" select="if > ($serialize.omit-xml-declaration='yes') then (1) else (0)"/> > > <p:with-option name="standalone" select="$serialize.standalone"/> > > <p:with-option name="undeclare-prefixes" select="if > ($serialize.undeclare-prefixes='yes') then (1) else (0)"/> > > <p:with-option name="version" select="$serialize.version"/> > > <p:with-option name="href" select="$store.href"/> > > </p:store> > > </p:when> > > <p:otherwise> > > <!-- Il n'y a aucun output avec le bon format, ni d'output générique : on > fait une sérialisation par défaut en xml --> > > <!--<cx:message><p:with-option name="message" select="'Il n'y a aucun > output avec le bon format, ni d'output générique : on fait une > sérialisation par défaut (selon xproc)'"/></cx:message>--> > > <p:store> > > <p:with-option name="href" select="$resultdoc.uri"/> > > </p:store> > > </p:otherwise> > > </p:choose> > > </p:for-each> > > <!-- 5. OUTPUT --> > > <p:identity><p:input port="source"><p:pipe port="result" > step="transform"/></p:input></p:identity> > > <igs:logFile><p:with-option name="href" > select="resolve-uri(concat($debug_folder_name,'/',$debug.file.name > ),$xml.uri)"/></igs:logFile> > > </p:group> > > </p:declare-step> > > > > > <!--+=========================================================================================+ > > | Step "igs:logFile" > > | Effectue la sauvegarde de la source XML courante > dans un fichier si le paramètre debug est activé. > > | Options : > > | href (obligatoire) : URI du fichier à créer avec > le contenu de la source XML courante > > | method (facultatif) : la méthode de sérialisation > (xml' par défaut) > > | indent (facultatif) : 'true' (par défaut) pour > indenter le contenu dans le fichier de sortie, ou 'false' pour ne pas > l'indenter. > > > +=========================================================================================+--> > > <p:declare-step type="igs:logFile" name="current"> > > <p:input port="source" sequence="true"/> <!--fixme : > sequence="true" vraiment ?--> > > <p:output port="result" sequence="true"><p:pipe > port="source" step="current"/></p:output> > > <p:input port="parameters" kind="parameter"/> > > <p:option name="href" required="true" > cx:type="xsd:anyURI"/> > > <p:option name="method" select="'xml'"/> > > <p:option name="indent" select="'true'"/> > > <p:wrap-sequence wrapper="sequence"/> > > <p:parameters name="params"/> > > <p:group> > > <p:variable name="debug" > select="(//param[@name='debug']/@value, false())[1]"><p:pipe > port="parameters" step="params"/></p:variable> > > <p:choose> > > <p:when > test="matches(string($debug),'(true|1)')"> > > > <cx:message><p:with-option name="message" select="concat('[INFO] Fichier > debug enregistre ici : ', $href)"/></cx:message> > > <p:store> > > > <p:with-option name="href" select="$href"/> > > > <p:with-option name="method" select="$method"/> > > > <p:with-option name="indent" select="$indent"/> > > </p:store> > > </p:when> > > <p:otherwise> > > <!-- La sortie > est déjà générée: c'est la même que l'entrée --> > > <p:sink/> > > </p:otherwise> > > </p:choose> > > </p:group> > > </p:declare-step> > > > > 2014-01-21 15:34 GMT+01:00 RICAUD-DUSSARGET Matthieu < > matthieu.ricaud@igs-cp.fr>: > > Hi Geert, > > > > Just mentionned you ;) as I was responding to Florent last mail, I have > just read yours, thanks for the suggests ! > > > > I've just tried a saxon:evaluate on character-map/@string but it tries to > evaluate as an xpath string, which lead to an error : > > SEVERE: Pipeline failed: net.sf.saxon.s9api.SaxonApiException: Static > error in XPath expression supplied to saxon:evaluate: Invalid QName {á} > > > > For the moment I don't have time to continue, but playing with codepoints > might be a pist ! > > > > Best regards, > > Matthieu > > > > > > > > 2014/1/21 Geert J. <geert.josten@dayon.nl> > > > > If you are only talking about numeric entities, you could perhaps use the > codepoints functions to convert number to unicode char. Otherwise, I would > think about trying to do an eval on your string. Sure Saxon has an eval > function either in XSLT or in XQuery. You could also eval on XProc I > thought, but maybe that overcomplicates things more than you want.. > > > > Sounds like character mapping could be a useful addition to XProc vNext? > > > > Cheers > > > > *Van:* RICAUD-DUSSARGET Matthieu [mailto:matthieu.ricaud@igs-cp.fr] > *Verzonden:* maandag 20 januari 2014 11:10 > *Aan:* XProc Dev > *Onderwerp:* Re: p:store serialization "character-map like" > > > > Oups not Levex but "Lexev" by Andrew Welch (http://andrewjwelch.com/lexev/) > ! > > > > I've tried : <xsl:value-of select="concat('&',$entity.name,';')" > disable-output-escaping="yes"/> > > where $entity.name is "160" > > > > But I still get "&160;" > > It seems disable-output-escaping="yes" doesn't work when running an > <p:xslt> as seen on http://markmail.org/message/3wig52gf3xkwwsdc > > > > So I think I will let this away and give an error message in case of > character map with such escape entity "&{entité};". > > > > Regards > > > > > > > > > > 2014/1/20 RICAUD-DUSSARGET Matthieu <matthieu.ricaud@igs-cp.fr> > > Hi all, > > > > Character-map is not allowed as an option of p:store ( > http://www.w3.org/TR/2010/REC-xproc-20100511/#serialization-options), I > don't really understand why and we really need this in our process, so I'm > trying to define a declare-step that does the trick (for > xsl:result-document at least) : > > > > 1. tranform a bit the xslt by : > > - adding the @format to the @href of any xsl:result-document (I will > then be able to get the @format from p:base-uri()) > > - adding an identity template that output the xsl:output and > xsl:character-maps > > > > 2. Reading this secondary output so I can pass dynamicly the serialization > options (xsl:ouptut) to the p:store > > > > 3. Adding an xslt step that read the corresponding xsl:character-maps in > the secondary output to operate a regex replacement of the matchings > characters. > > > > Well this is a try, any suggests on this is welcome. > > > > For the moment the only thing I'm not abale to do is to deal with this > kind of character map : > > > > <xsl:output-character character=" " string="&#160;"/> <!-- THIN > SPACE replace by NO-BREAK SPACE --> > > > > Using saxon out of xproc this character map rule will replace any thin > space " " by a no break space " ", but when trying to replace it > with a regex (in xslt, see the process above) I get "&160;" in the > output. > > > > Of course I could directly write the good entity : > > <xsl:output-character character=" " string=" "/> > > and this would work fine. > > But the goal here is to really implement character-map mechanism. > > By the way outputing   can make it easier to read the output file and > see no break spaces. > > > > I think this is not possible "construct" dynamicly an entity with xslt or > maybe by using specials saxon function ? but I don't manage to, for > instance : > > with xproc/calabash, <saxon:entity-ref name="160" > xsl:extension-element-prefixes="saxon"/> also output "&160;" and not > the desired "&160;" > > > > > > I'll have a look at levex, but any suggest is welcome. > > > > Regards, > > Matthieu > > > > -- > > Matthieu Ricaud-Dussarget > > IGS-CP - Développeur XML > > 05 45 37 09 49 > > > > > > -- > > Matthieu Ricaud-Dussarget > > IGS-CP - Développeur XML > > 05 45 37 09 49 > > > > > > -- > > Matthieu Ricaud-Dussarget > > IGS-CP - Développeur XML > > 05 45 37 09 49 > > > > > > -- > > Matthieu Ricaud-Dussarget > > IGS-CP - Développeur XML > > 05 45 37 09 49 > -- Matthieu Ricaud-Dussarget IGS-CP - Développeur XML 05 45 37 09 49
Received on Wednesday, 19 February 2014 08:55:37 UTC