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

Received on Monday, 17 February 2014 13:42:08 UTC