Re: p:store serialization "character-map like"

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="&#8201;" string="&#160;"/> plutôt que
> <xsl:output-character character="&#8201;" string="&amp;#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,&quot;',
> $href_format_sep ,'&quot;,@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,'&#10;',
>
> 'resultdoc.serialized_uri : ',$resultdoc.serialized_uri,'&#10;',
>
> 'resultdoc.uri : ',$resultdoc.uri,'&#10;',
>
> 'resultdoc.format : ',$resultdoc.format,'&#10;',
>
> 'store.href: ',$store.href,'&#10;'
>
> )"/>
>
> </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', '&#10;',
>
> '$serialize.method=',$serialize.method, '&#10;',
>
> '$serialize.encoding=',$serialize.encoding, '&#10;',
>
> '$serialize.byte-order-mark=',$serialize.byte-order-mark, '&#10;',
>
> '$serialize.cdata-section-elements=',$serialize.cdata-section-elements,
> '&#10;',
>
> '$serialize.doctype-system=',$serialize.doctype-system, '&#10;',
>
> '$serialize.doctype-public=',$serialize.doctype-public, '&#10;',
>
> '$serialize.escape-uri-attributes=',$serialize.escape-uri-attributes,
> '&#10;',
>
> '$serialize.include-content-type=',$serialize.include-content-type,
> '&#10;',
>
> '$serialize.indent=',$serialize.indent, '&#10;',
>
> '$serialize.media-type=',$serialize.media-type, '&#10;',
>
> '$serialize.normalization-form=',$serialize.normalization-form, '&#10;',
>
> '$serialize.omit-xml-declaration=',$serialize.omit-xml-declaration,
> '&#10;',
>
> '$serialize.standalone=',$serialize.standalone, '&#10;',
>
> '$serialize.undeclare-prefixes=',$serialize.undeclare-prefixes, '&#10;',
>
> '$serialize.version=',$serialize.version, '&#10;'
>
> )"/>
>
> </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,'&amp;(.*?);')">
>
> <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('&amp;',$entity.name,';')"
> disable-output-escaping="yes"/>
>
> where $entity.name is "160"
>
>
>
> But I still get "&amp;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 "&amp;{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="&#8201;" string="&amp;#160;"/> <!-- THIN
> SPACE replace by NO-BREAK SPACE -->
>
>
>
> Using saxon out of xproc this character map rule will replace any thin
> space "&#8201;" by a no break space "&#160;", but when trying to replace it
> with a regex (in xslt, see the process above) I get "&amp;160;" in the
> output.
>
>
>
> Of course I could directly write the good entity :
>
> <xsl:output-character character="&#8201;" string="&#160;"/>
>
> and this would work fine.
>
> But the goal here is to really implement character-map mechanism.
>
> By the way outputing &#160; 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 "&amp;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