XSLT1替换占位符

时间:2017-03-23 17:53:24

标签: xml xslt xpath xslt-1.0 xsl-fo

我必须用xpath替换一些像$$ RUOLO ^这样的占位符,这就是结果xsl:fo:

 <fo:block>e per il ruolo $$RUOLO^ , funzione <xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="/root/ddx[@id='rsSelect']/r/FUNZIONE_BREVE"/> da lei ricoperta per la specifica informazione con la seguente motivazione $$DESCRIZIONE_ISCRIZIONE^ .</fo:block> 

我用select =“/ root / ddx [@ id ='rsSelect'] / r / FUNZIONE_BREVE”替换了$$ FUNZIONE ^ /&gt;但这种剂量适用于RUOLO。为什么不呢?

就像我一样:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo fn xsl XWC" 
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:XWC="http://www.netbureau.it/XWC/2.0">

<xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes" indent="yes"/>

<!-- non toccare -->
    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>

<!-- fine non toccare -->

<!-- match templates per sostituzione variabili-->

    <xsl:template match="fo:block[contains(text(),'$$EVENTO^')] | fo:inline[contains(text(),'$$EVENTO^')]">
        <xsl:call-template  name="eventotmp"/>
    </xsl:template>

    <xsl:template match="fo:block[contains(text(),'$$DECORRENZA^')] | fo:inline[contains(text(),'$$DECORRENZA^')]">
        <xsl:call-template  name="decorrenzatmp">
            <xsl:with-param name="text"><xsl:value-of select="text()"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>

    <xsl:template match="fo:block[contains(text(),'$$DESCRIZIONE_ISCRIZIONE^')] | fo:inline[contains(text(),'$$DESCRIZIONE_ISCRIZIONE^')]">
        <xsl:call-template  name="descrizionetmp">
            <xsl:with-param name="text"><xsl:value-of select="text()"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>

    <xsl:template match="fo:block[contains(text(),'$$TIPOLOGIA_INFORMAZIONE_PRIVILEGIATA^')] | fo:inline[contains(text(),'$$TIPOLOGIA_INFORMAZIONE_PRIVILEGIATA^')]">
        <xsl:call-template  name="tipologiatmp">
        <xsl:with-param name="text"><xsl:value-of select="text()"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>

    <xsl:template match="fo:block[contains(text(),'$$RUOLO^')] | fo:inline[contains(text(),'$$RUOLO^')]">
        <xsl:call-template  name="ruolotmp">
        <xsl:with-param name="text"><xsl:value-of select="text()"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>

    <xsl:template match="fo:block[contains(text(),'$$FUNZIONE^')] | fo:inline[contains(text(),'$$FUNZIONE^')]">
        <xsl:call-template  name="funzionetmp">
        <xsl:with-param name="text"><xsl:value-of select="text()"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>

    <xsl:template match="fo:block[contains(text(),'$$NR_ARTICOLO^')] | fo:inline[contains(text(),'$$NR_ARTICOLO^')]">
        <xsl:call-template  name="nrarticolotmp">
        <xsl:with-param name="text"><xsl:value-of select="text()"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>

    <xsl:template match="fo:block[contains(text(),'$$CODICE_INFORMAZIONE^')] | fo:inline[contains(text(),'$$CODICE_INFORMAZIONE^')]">
        <xsl:call-template  name="codinfotmp">
        <xsl:with-param name="text"><xsl:value-of select="text()"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>

    <xsl:template match="fo:block[contains(text(),'$$CIP^')] | fo:inline[contains(text(),'$$CIP^')]">
        <xsl:call-template  name="ciptmp">
        <xsl:with-param name="text"><xsl:value-of select="text()"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>

    <xsl:template match="fo:block[contains(text(),'$$PROTOCOLLO^')] | fo:inline[contains(text(),'$$PROTOCOLLO^')]">
        <xsl:call-template  name="protocollotmp">
        <xsl:with-param name="text"><xsl:value-of select="text()"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>

    <xsl:template match="fo:block[contains(text(),'$$EMITTENTE^')] | fo:inline[contains(text(),'$$EMITTENTE^')]">
        <xsl:call-template  name="emittentetmp">
        <xsl:with-param name="text"><xsl:value-of select="text()"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>

    <xsl:template match="fo:block[contains(text(),'$$AREA_COMPETENZA^')] | fo:inline[contains(text(),'$$AREA_COMPETENZA^')]">
        <xsl:call-template  name="areacompetenzatmp">
        <xsl:with-param name="text"><xsl:value-of select="text()"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>




<!-- end match templates -->
<!--  non toccare -->

    <!--  match/copia tutti i commenti  -->
    <xsl:template match='comment()'>
     <xsl:comment><xsl:value-of select="."/></xsl:comment>
    </xsl:template>

    <!--  match/copia di eventuali istruzioni <?elementostart> ecc : ovvero eventuali processing istructions -->
    <xsl:template match='processing-instruction()'>
     <xsl:processing-instruction name="{name()}">
      <xsl:value-of select="."/>
     </xsl:processing-instruction>
    </xsl:template>


    <!--  funzione identità : match/copia di tutti tag che contengono testo e non, compresi i CDATA :
     "*" seleziona solo i tag,   
     node() seleziona tutti i nodi testo, non testo ed i cdata, 
     @* seleziona tutti gli attributi, 
     | => OR
     i commenti non vengono copiati, vedere template comment()

     -->
    <xsl:template match="@*|*">
     <xsl:copy>
       <xsl:apply-templates select="@*|node()"/>
     </xsl:copy>
    </xsl:template>

<!-- end non toccare -->    


<!-- definizione templates per sostituzione variabili -->
    <xsl:template name="eventotmp">
    <xsl:element name="fo:block">
            <xsl:element name="xsl:value-of">
                <xsl:attribute name="select">/root/ddx[@id='rsSelect']/r/TITOLO</xsl:attribute>
            </xsl:element>
    <!--        <xsl:value-of select="/root/ddx[@id='rsSelect']/r/TITOLO"/>  -->
    </xsl:element>
    </xsl:template>

    <xsl:template name="decorrenzatmp">
    <xsl:param name="text"/>
        <xsl:element name="fo:block">
            <xsl:value-of select="substring-before($text,'$$DECORRENZA^')"/>
            <xsl:element name="xsl:value-of">
                <xsl:attribute name="select">/root/ddx[@id='rsSelect']/r/DATA_ISCRIZIONE_ESTESA</xsl:attribute>
            </xsl:element>
            <xsl:value-of select="substring-after($text,'$$DECORRENZA^')"/>
        </xsl:element>
    </xsl:template>



    <xsl:template name="descrizionetmp">
    <xsl:param name="text"/>
        <xsl:element name="fo:block">
<!--        <xsl:text>RAGIONE: </xsl:text> -->
            <xsl:value-of select="substring-before($text,'$$DESCRIZIONE_ISCRIZIONE^')"/>
            <xsl:element name="xsl:value-of">
                <xsl:attribute name="select">/root/ddx[@id='rsSelect']/r/DESCRIZIONE_ISCRIZIONE</xsl:attribute>
            </xsl:element>
            <xsl:value-of select="substring-after($text,'$$DESCRIZIONE_ISCRIZIONE^')"/>
<!--        <xsl:text>RAGIONE: </xsl:text><xsl:value-of select="/root/ddx[@id='rsSelect']/r/DESCRIZIONE_ISCRIZIONE"/> -->
        </xsl:element>
    </xsl:template>



    <xsl:template name="tipologiatmp">
    <xsl:param name="text"/>
        <xsl:element name="fo:block">
<!--        <xsl:text>TIPOLOGIA: </xsl:text> -->
        <xsl:value-of select="substring-before($text,'$$TIPOLOGIA_INFORMAZIONE_PRIVILEGIATA^')"/>
        <xsl:element name="xsl:value-of">
            <xsl:attribute name="select">/root/ddx[@id='rsSelect']/r/TIPO_INFORMAZIONE_PRIVILEGIATA</xsl:attribute>
        </xsl:element>
<!--        <xsl:text>TIPOLOGIA: </xsl:text><xsl:value-of select="/root/ddx[@id='rsSelect']/r/TIPO_INFORMAZIONE_PRIVILEGIATA"/> -->
        <xsl:value-of select="substring-after($text,'$$TIPOLOGIA_INFORMAZIONE_PRIVILEGIATA^')"/>
        </xsl:element>
    </xsl:template>

    <xsl:template name="ruolotmp">
    <xsl:param name="text"/>
        <xsl:element name="fo:block">
<!--        <xsl:text>RUOLO: </xsl:text> -->
        <xsl:value-of select="substring-before($text,'$$RUOLO^')"/>
        <xsl:element name="xsl:value-of">
            <xsl:attribute name="select">/root/ddx[@id='rsSelect']/r/RUOLO_BREVE</xsl:attribute>
        </xsl:element>
        <xsl:value-of select="substring-after($text,'$$RUOLO^')"/>
<!--        <xsl:text>RUOLO: </xsl:text><xsl:value-of select="/root/ddx[@id='rsSelect']/r/RUOLO_BREVE"/> -->
        </xsl:element>
    </xsl:template>



    <xsl:template name="funzionetmp">
    <xsl:param name="text"/>
    <xsl:element name="fo:block">
<!--        <xsl:text>FUNZIONE: </xsl:text> -->
        <xsl:value-of select="substring-before($text,'$$FUNZIONE^')"/>
        <xsl:element name="xsl:value-of">
            <xsl:attribute name="select">/root/ddx[@id='rsSelect']/r/FUNZIONE_BREVE</xsl:attribute>
        </xsl:element>
<!--        <xsl:text>FUNZIONE: </xsl:text><xsl:value-of select="/root/ddx[@id='rsSelect']/r/FUNZIONE_BREVE"/> -->
        <xsl:value-of select="substring-after($text,'$$FUNZIONE^')"/>
    </xsl:element>
    </xsl:template>




    <xsl:template name="nrarticolotmp">
    <xsl:param name="text"/>
    <xsl:element name="fo:block">
<!--        <xsl:text>NR. ARTICOLO: </xsl:text> -->
        <xsl:value-of select="substring-before($text,'$$NR_ARTICOLO^')"/>
        <xsl:element name="xsl:value-of">
            <xsl:attribute name="select">/root/ddx[@id='rsSelect']/r/NR_ARTICOLO</xsl:attribute>
        </xsl:element>
<!--        <xsl:text>NR. ARTICOLO: </xsl:text><xsl:value-of select="/root/ddx[@id='rsSelect']/r/NR_ARTICOLO"/> -->
        <xsl:value-of select="substring-after($text,'$$NR_ARTICOLO^')"/>
    </xsl:element>
    </xsl:template>

    <xsl:template name="codinfotmp">
    <xsl:param name="text"/>
    <xsl:element name="fo:block">
<!--        <xsl:text>CODICE INFORMAZIONE: </xsl:text> -->
        <xsl:value-of select="substring-before($text,'$$CODICE_INFORMAZIONE^')"/>
        <xsl:element name="xsl:value-of">
            <xsl:attribute name="select">/root/ddx[@id='rsSelect']/r/CODICE_INFORMAZIONE</xsl:attribute>
        </xsl:element>
        <xsl:value-of select="substring-after($text,'$$CODICE_INFORMAZIONE^')"/>
<!--        <xsl:text>CODICE INFORMAZIONE: </xsl:text><xsl:value-of select="/root/ddx[@id='rsSelect']/r/CODICE_INFORMAZIONE"/> -->
    </xsl:element>
    </xsl:template>

    <xsl:template name="ciptmp">
    <xsl:param name="text"/>
    <xsl:element name="fo:block">
<!--        <xsl:text>CODICE CIP: </xsl:text> -->
        <xsl:value-of select="substring-before($text,'$$CIP^')"/>
        <xsl:element name="xsl:value-of">
            <xsl:attribute name="select">/root/ddx[@id='rsSelect']/r/CODICE_PRATICA</xsl:attribute>
        </xsl:element>
        <xsl:value-of select="substring-after($text,'$$CIP^')"/>
<!--        <xsl:text>CIP:</xsl:text><xsl:value-of select="/root/ddx[@id='rsSelect']/r/CODICE_PRATICA"/> -->
    </xsl:element>
    </xsl:template>

    <xsl:template name="protocollotmp">
    <xsl:param name="text"/>
    <xsl:element name="fo:block">
<!--        <xsl:text>PROTOCOLLO: </xsl:text> -->
        <xsl:value-of select="substring-before($text,'$$PROTOCOLLO^')"/>
        <xsl:element name="xsl:value-of">
            <xsl:attribute name="select">/root/ddx[@id='rsSelect']/r/PROTOCOLLO</xsl:attribute>
        </xsl:element>
        <xsl:value-of select="substring-after($text,'$$PROTOCOLLO^')"/>
<!--        <xsl:text>PROTOCOLLO: </xsl:text><xsl:value-of select="/root/ddx[@id='rsSelect']/r/PROTOCOLLO"/> -->
    </xsl:element>
    </xsl:template>

    <xsl:template name="emittentetmp">
    <xsl:param name="text"/>
    <xsl:element name="fo:block">
<!--    <xsl:text>EMITTENTE: </xsl:text> -->
        <xsl:value-of select="substring-before($text,'$$EMITTENTE^')"/>
        <xsl:element name="xsl:value-of">
            <xsl:attribute name="select">/root/ddx[@id='rsSelect']/r/EMITTENTE_ESTESA</xsl:attribute>
        </xsl:element>

        <xsl:value-of select="substring-after($text,'$$EMITTENTE^')"/>
    </xsl:element>
    </xsl:template>

    <xsl:template name="areacompetenzatmp">
    <xsl:param name="text"/>
    <xsl:element name="fo:block">
<!--    <xsl:text>EMITTENTE: </xsl:text> -->
        <xsl:value-of select="substring-before($text,'$$AREA_COMPETENZA^')"/>
        <xsl:element name="xsl:value-of">
            <xsl:attribute name="select">/root/ddx[@id='rsSelect']/r/AREA_COMPETENZA</xsl:attribute>
        </xsl:element>
<!--        <xsl:text>EMITTENTE: </xsl:text><xsl:value-of select="/root/ddx[@id='rsSelect']/r/EMITTENTE_ESTESA"/> -->
        <xsl:value-of select="substring-after($text,'$$AREA_COMPETENZA^')"/>
    </xsl:element>
    </xsl:template>


</xsl:stylesheet>

我只使用这个模板,就像最后一个链替换(管道)一样。为什么RUOLO和DESCRIZIONE_ISCRIZIONE的预期不一样?

由于

拉​​吉

谢谢@JLRishe 它适用于替换,但它不考虑所有文本出现在同一行没有CARRIAGE RETURN保存.. XSL FO输入看起来像:

 <fo:page-sequence master-reference="all-pages"><fo:static-content flow-name="page-header"><fo:block font-size="small" text-align="center" space-before="0.5in" space-before.conditionality="retain"/></fo:static-content><fo:static-content flow-name="page-footer"><fo:block font-size="small" text-align="center" space-after="0.5in" space-after.conditionality="retain">- <fo:page-number/> -</fo:block></fo:static-content><fo:flow flow-name="xsl-region-body"><fo:block role="html:body">
  <fo:block space-before="1em" space-after="1em" role="html:p">ISCRIZIONE PRIVILEGIATA</fo:block> 
  <fo:block space-before="1em" space-after="1em" role="html:p"><fo:block role="html:br"/>Comunicazione relativa all'Elenco dele persone che hanno accesso alle informazioni privilegiate istituito ai sensi del</fo:block> 
  <fo:block space-before="1em" space-after="1em" role="html:p">$$EVENTO^</fo:block> 
  <fo:block space-before="1em" space-after="1em" role="html:p">Con la presente Le comunichiamo che in data $$DECORRENZA^ è stato iscritto nel ..) (“MAR”) e dalla relativa disciplina di attuazione contenuta nel Regolamento di esecuzione .. – con riferimento a:</fo:block> 
  <fo:block space-before="1em" space-after="1em" role="html:p"> </fo:block> 
  <fo:block space-before="1em" space-after="1em" role="html:p">Tipologia informazione privilegiata $$TIPOLOGIA_INFORMAZIONE_PRIVILEGIATA^ e per il ruolo $$RUOLO^, funzione $$FUNZIONE^ da lei ricoperta per la specifica informazione privilegiata con la seguente motivazione $$DESCRIZIONE_ISCRIZIONE^.</fo:block> 
  <fo:block space-before="1em" space-after="1em" role="html:p">Si chiede di far preciso riferimento alla “Procedura per la gestione del Registro delle Persone che hanno accesso a Informazioni Privilegiate” (la “Procedura”) che risulta in vigore che risulta consultabile sul sito internet della Società al seguente indirizzo</fo:block> 
  <fo:block space-before="1em" space-after="1em" role="html:p"> </fo:block> 
  <fo:block space-before="1em" space-after="1em" role="html:p">Per la nozione di informazione privilegiata si rinvia all’articolo 7 MAR riprodotto in allegato alla presente, nonché alla procedura denominata “Procedura per la gestione interna e per la comunicazione al pubblico di Informazioni xxx” adottata dalla Società che parimenti risulta consultabile sul sito internet all’indirizzo sopra indicato.</fo:block> 
  <fo:block space-before="1em" space-after="1em" role="html:p"> </fo:block> 
  <fo:block space-before="1em" space-after="1em" role="html:p">$$EMITTENTE^</fo:block> 
  <fo:block space-before="1em" space-after="1em" role="html:p">$$CIP^</fo:block> 
  <fo:block space-before="1em" space-after="1em" role="html:p">$$PROTOCOLLO^</fo:block> 
  <fo:block space-before="1em" space-after="1em" role="html:p">$$AREA_COMPETENZA^</fo:block> 
  <fo:block space-before="1em" space-after="1em" role="html:p">Per presa visione e ritiro di copia</fo:block> 
  <fo:block space-before="1em" space-after="1em" role="html:p">Data ...........................................</fo:block> 
  <fo:block space-before="1em" space-after="1em" role="html:p">Firma .....................................................</fo:block> 
  <fo:block space-before="1em" space-after="1em" role="html:p"> </fo:block>
 </fo:block></fo:flow></fo:page-sequence>
</fo:root>

1 个答案:

答案 0 :(得分:1)

这里的问题是,在将模板应用于节点时,单个节点只能由一个模板匹配。由于您的FUNZIONE模板的优先级高于RUOLO或DESCRIZIONE_ISCRIZIONE的模板(因为它出现的时间晚于它们),因此正在使用的模板。

解决方案是使用递归方法逐步替换占位符,直到不再需要替换。以下是这样做,也消除了XSLT中的大量重复:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo vr"
                xmlns:vr="my-variables"
>
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />

  <vr:substitutions>
    <substitution key="$$FUNZIONE^" path="/root/ddx[@id='rsSelect']/r/FUNZIONE_BREVE" />
    <substitution key="$$RUOLO^" path="/root/ddx[@id='rsSelect']/r/RUOLO_BREVE" />
    <substitution key="$$CODICE_INFORMAZIONE^" path="/root/ddx[@id='rsSelect']/r/CODICE_INFORMAZIONE" />
    <substitution key="$$DESCRIZIONE_ISCRIZIONE^" path="/root/ddx[@id='rsSelect']/r/DESCRIZIONE_ISCRIZIONE" />
  </vr:substitutions>

  <xsl:variable name="substitutions" select="document('')/*/vr:substitutions/substitution" />

  <!-- Identity template -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="fo:block[contains(., '$$')] | fo:inline[contains(., '$$')]">
    <fo:block>
      <xsl:call-template name="PerformSubstitutions">
        <xsl:with-param name="text" select="." />
      </xsl:call-template>
    </fo:block>
  </xsl:template>

  <xsl:template name="PerformSubstitutions">
    <xsl:param name="text" />
    <xsl:variable name="substitution" select="$substitutions[contains($text, @key)]" />

    <xsl:choose>
      <xsl:when test="$substitution">
        <!-- Recursively call PerformSubstitutions on portion before placeholder-->
        <xsl:call-template name="PerformSubstitutions">
          <xsl:with-param name="text" select="substring-before($text, $substitution/@key)" />
        </xsl:call-template>
        <!-- Insert xsl:value-of -->
        <xsl:element name="xsl:value-of">
          <xsl:attribute name="select">
            <xsl:value-of select="$substitution/@path"/>
          </xsl:attribute>
        </xsl:element>
        <!-- Recursively call PerformSubstitutions on portion after placeholder-->
        <xsl:call-template name="PerformSubstitutions">
          <xsl:with-param name="text" select="substring-after($text, $substitution/@key)" />
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <!-- No substitutions found. Just output the text -->
        <xsl:value-of select="$text"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

您可以通过向<vr:substitutions>部分添加更多元素来处理所需的占位符。

在此输入XML上运行时:

<n xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <fo:inline>Some text $$FUNZIONE^ and $$RUOLO^ other text $$DESCRIZIONE_ISCRIZIONE^ </fo:inline>
  <fo:block>Some more text $$CODICE_INFORMAZIONE^ yay.</fo:block>
</n>

输出结果为:

<n xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <fo:block>Some text <xsl:value-of select="/root/ddx[@id='rsSelect']/r/FUNZIONE_BREVE" /> and <xsl:value-of select="/root/ddx[@id='rsSelect']/r/RUOLO_BREVE" /> other text <xsl:value-of select="/root/ddx[@id='rsSelect']/r/DESCRIZIONE_ISCRIZIONE" /> </fo:block>
  <fo:block>Some more text <xsl:value-of select="/root/ddx[@id='rsSelect']/r/CODICE_INFORMAZIONE" /> yay.</fo:block>
</n>