Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1208 connectés 

  FORUM HardWare.fr
  Programmation
  XML/XSL

  Remplacer chaque caractère par autre en gardant la structure [Résolu]

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Remplacer chaque caractère par autre en gardant la structure [Résolu]

n°2429211
smilodongo​r
Posté le 14-10-2022 à 08:07:04  profilanswer
 

Bien le bonjour la communauté  :hello: .
 
Je vous expose mon souci. Un nouveau challenge à votre sagacité... :lol:  
 Je travaille depuis quelques temps avec les principes XLST pour modifier des xmls qui sont la source de notre "Document Management System".
Notre business, par charte graphique, ne veut pas de bullet mais un tiret pour l'indentation (puce).
Je ne peux agir que sur le contenu des valeurs des noeuds (pas dans la config du tinymce ou du DMS).
Mon but étant de remplacer chaque occurrence bullet "" par un tiret (hyphen) tout en gardant la structure dans son noeud général "FreeText" (structure non modifiable).
A ce point, les remplacements s'effectuent mais il perd tous les noeuds enfants... :pfff:  
 
J'ai donc ceci comme xml, en entrée :
 

Citation :

<?xml version="1.0" encoding="UTF-8"?>
<form>
 <Document>
  <Header>
   <Message>
    <MessageOriginalName>QUICK_DOCUMENTS</MessageOriginalName>
   </Message>
  </Header>
 </Document>
 <Eform>
  <Selection_Heading1>FourthActor_1</Selection_Heading1>
  <Selection_Heading2>Beneficiary_2</Selection_Heading2>
  <Selection_Heading3>Beneficiary_1</Selection_Heading3>
  <FreeText mediatype="text/xslfo">
   <fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <fo:block>
     <fo:list-block margin-bottom="12pt" margin-top="12pt">
      <fo:list-item>
       <fo:list-item-label end-indent="label-end()">
        <fo:block>•</fo:block>
       </fo:list-item-label>
       <fo:list-item-body start-indent="body-start()">
        <fo:block>Ligne 1</fo:block>
       </fo:list-item-body>
      </fo:list-item>
      <fo:list-item>
       <fo:list-item-label end-indent="label-end()">
        <fo:block>•</fo:block>
       </fo:list-item-label>
       <fo:list-item-body start-indent="body-start()">
        <fo:block>Ligne 2</fo:block>
       </fo:list-item-body>
      </fo:list-item>
     </fo:list-block>
    </fo:block>
   </fo:block>
  </FreeText>
  <SelectedAll>true</SelectedAll>
 </Eform>
</form>


 
Et je voudrais par transformation xsl, ceci en sortie :
 

Citation :

<?xml version="1.0" encoding="UTF-8"?>
<form>
 <Document>
  <Header>
   <Message>
    <MessageOriginalName>QUICK_DOCUMENTS</MessageOriginalName>
   </Message>
  </Header>
 </Document>
 <Eform>
  <Selection_Heading1>FourthActor_1</Selection_Heading1>
  <Selection_Heading2>Beneficiary_2</Selection_Heading2>
  <Selection_Heading3>Beneficiary_1</Selection_Heading3>
  <FreeText mediatype="text/xslfo">
   <fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <fo:block>
     <fo:list-block margin-bottom="12pt" margin-top="12pt">
      <fo:list-item>
       <fo:list-item-label end-indent="label-end()">
        <fo:block>-</fo:block>
       </fo:list-item-label>
       <fo:list-item-body start-indent="body-start()">
        <fo:block>Ligne 1</fo:block>
       </fo:list-item-body>
      </fo:list-item>
      <fo:list-item>
       <fo:list-item-label end-indent="label-end()">
        <fo:block>-</fo:block>
       </fo:list-item-label>
       <fo:list-item-body start-indent="body-start()">
        <fo:block>Ligne 2</fo:block>
       </fo:list-item-body>
      </fo:list-item>
     </fo:list-block>
    </fo:block>
   </fo:block>
  </FreeText>
  <SelectedAll>true</SelectedAll>
 </Eform>
</form>


 
Grâce à mon dernier xsl ci-dessous, les remplacements s'effectuent mais il perd tous les noeuds enfants
 

Citation :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all">
 <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/>
 <xsl:param name="replace" select="'•'"/>
 <xsl:param name="by" select="'-'"/>
 <xsl:template match="*">
  <xsl:if test="/form/Document/Header/Message/MessageOriginalName[contains(., 'QUICK_DOCUMENTS')]">
   <xsl:choose>
    <xsl:when test="name()='FreeText'">
     <xsl:variable name="FT"><xsl:value-of select="string(/form/Eform/FreeText)"/></xsl:variable>
     <FreeText mediatype="text/xslfo"><xsl:value-of select="replace($FT, $replace, $by)"/></FreeText>
    </xsl:when>
    <xsl:otherwise>
     <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
     </xsl:copy>
    </xsl:otherwise>
   </xsl:choose>
  </xsl:if>
  <xsl:if test="not(/form/Document/Header/Message/MessageOriginalName[contains(., 'QUICK_DOCUMENTS')])">
   <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
   </xsl:copy>
  </xsl:if>
 </xsl:template>
 <xsl:template match="@*|text()|comment()|processing-instruction()">
  <xsl:copy-of select="."/>
 </xsl:template>
</xsl:stylesheet>


 
J'obtiens ce mauvais xml généré :
 

Citation :

<?xml version="1.0" encoding="UTF-8"?>
<form>
 <Document>
  <Header>
   <Message>
    <MessageOriginalName>QUICK_DOCUMENTS</MessageOriginalName>
   </Message>
  </Header>
 </Document>
 <Eform>
  <Selection_Heading1>FourthActor_1</Selection_Heading1>
  <Selection_Heading2>Beneficiary_2</Selection_Heading2>
  <Selection_Heading3>Beneficiary_1</Selection_Heading3>
  <FreeText mediatype="text/xslfo">-Ligne 1-Ligne 2</FreeText>
  <SelectedAll>true</SelectedAll>
 </Eform>
</form>


 
Si une âme charitable voudrait bien m'aider, je le remercie déjà d'avance... :ange:


Message édité par smilodongor le 17-10-2022 à 09:52:02
mood
Publicité
Posté le 14-10-2022 à 08:07:04  profilanswer
 

n°2429316
rufo
Pas me confondre avec Lycos!
Posté le 14-10-2022 à 19:13:57  profilanswer
 

Cale fait pas ça ?
https://stackoverflow.com/questions [...] ng-replace


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
n°2429388
gilou
Modérateur
Modzilla
Posté le 15-10-2022 à 17:36:45  profilanswer
 

Bonjour,
Cette feuille de style fait le taff :  
Elle copie tout a l'identique, sauf le cas particulier ou tu veux ta transformation/.
 

Code :
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <xsl:stylesheet  
  3.  version="2.0"  
  4.  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
  5.  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  6.  xmlns:fo="http://www.w3.org/1999/XSL/Format"
  7.  exclude-result-prefixes="#all">
  8.  
  9.  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  10.  
  11.  <!-- identity copy par défaut -->
  12.  <xsl:template match="document-node()|node()|@*">
  13.    <xsl:copy>
  14.      <xsl:apply-templates select="node()|@*"/>
  15.    </xsl:copy>
  16.  </xsl:template>
  17.  
  18.  <!-- spécialisation pour le cas particulier -->
  19.  <xsl:template match="fo:block[not(*) and string(.)='•']">
  20.    <fo:block>-</fo:block>
  21.  </xsl:template>
  22.  
  23. </xsl:stylesheet>


 
Notes :  

  • il y a des choses qui ne sont pas acceptées en xsl 1.0 ( #all et replace() ) dans ton code original, [ton outil semble les accepter] d’où mon passage en xsl 2.0. De toute façon, le xsl 2.0 est le minimum pour arriver a faire des choses utilisables en XSL (on est bientôt au 4.0, c'est en cours de finalisation depuis un an). Si tu as vraiment des contraintes xsl 1.0 ceci devrait faire le taff:
Code :
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <xsl:stylesheet  
  3.  version="1.0"  
  4.  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
  5.  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  6.  xmlns:fo="http://www.w3.org/1999/XSL/Format">
  7.  
  8.  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  9.  
  10.  <!-- identity copy par défaut -->
  11.  <xsl:template match="/|node()|@*">
  12.    <xsl:copy>
  13.      <xsl:apply-templates select="node()|@*"/>
  14.    </xsl:copy>
  15.  </xsl:template>
  16.  
  17.  <!-- spécialisation pour le cas particulier -->
  18.  <xsl:template match="fo:block[not(*) and string(.)='•']">
  19.    <xsl:element name="fo:block">-</xsl:element>
  20.  </xsl:template>
  21.  
  22. </xsl:stylesheet>


  • il est toujours bon de faire figurer les namespaces dont tu vas avoir besoin ( fo ) dans la partie xsl:stylesheet
  • match="fo:block[string(.)='•']" suffirait, mais match="fo:block[not(*) and string(.)='•']" optimise cela rejetant les fo:block contenant des éléments comme les deux premiers fo:block (imbriqués) de ton exemple, où la collecte de tout le texte des sous-éléments serait couteuse et inutile.


La même chose en xsl 3.0

Code :
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <xsl:stylesheet  
  3.  version="3.0"  
  4.  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
  5.  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  6.  xmlns:fo="http://www.w3.org/1999/XSL/Format"
  7.  exclude-result-prefixes="#all">
  8.  
  9.  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  10.  <!-- identity copy par défaut via le mode par défaut-->
  11.  <xsl:mode on-no-match="shallow-copy"/>
  12.  
  13.  <!-- spécialisation pour le cas particulier -->
  14.  <xsl:template match="fo:block[not(*) and string(.)='•']">
  15.    <fo:block>-</fo:block>
  16.  </xsl:template>
  17.  
  18. </xsl:stylesheet>


 
A+,


Message édité par gilou le 15-10-2022 à 18:18:17

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2429391
gilou
Modérateur
Modzilla
Posté le 15-10-2022 à 18:26:09  profilanswer
 

Note que si tu es dans une boite, et que tu as professionnellement et couramment besoin de transformer du XML, tu devrais avoir l'outil standard pour (Oxygen XML Editor). Et une licence saxon, si tu as besoin de faire de la transfo xsl dans tes process (et pas seulement utiliser du xml transformé)
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2429472
smilodongo​r
Posté le 17-10-2022 à 09:48:09  profilanswer
 

Grand merci à vous 2.
 
D'abord @rufo : effectivement, je m'étais basé sur cet article (tu peux remarquer que mon xsl y ressemble).
 
Mais surtout @gilou.
Cela fonctionne très bien. Ce que j'ai apprécié, ce sont tes explications et conseils.
Parfait ...et bravo
Bonne continuation à ce forum avec des personnes de bonnes volonté.
 
Peut-être qu'un jour, je pourrais également aider à mon tour....


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  XML/XSL

  Remplacer chaque caractère par autre en gardant la structure [Résolu]

 

Sujets relatifs
Supprimer le caractère & dans une chaineRegex récupérer valeur à partir d'un caractère
Recherche caractère unicodeComment remplacer getIntent ?
[resolut]passage d'un tableau de structure à une DLL Cerreur de compilation caractère incorrect
remplacer les noms par les imagesextraire dans une variable le contenu d'une structure
[PHP] Remplacer des mots dans une string par des valeurs d'un tableauRemplacer une lettre dans .txt POWERSHELL
Plus de sujets relatifs à : Remplacer chaque caractère par autre en gardant la structure [Résolu]


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR