[XSLT] déclaration de namespace et localisation attribut

déclaration de namespace et localisation attribut [XSLT] - XML/XSL - Programmation

Marsh Posté le 04-11-2011 à 15:31:23    

Bonjour,  
 
Complètement nouvelle dans le merveilleux monde XML/XSLT je dois trnasformer un document XML en un autre.  
 
J'ai déjà réussi quelques ptites choses mais là mes problèmes (qui ne sont pas reliés), je n'y trouve solution nulle part ...  
 
Mon XML de base :  

Code :
  1. <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
  2. xmlns:o="urn:schemas-microsoft-com:office:office"
  3. xmlns:x="urn:schemas-microsoft-com:office:excel"
  4. xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
  5. xmlns:html="http://www.w3.org/TR/REC-html40">
  6. <Worksheet ss:Name="Composants">
  7.    <Table ss:ExpandedColumnCount="22" ss:ExpandedRowCount="3" x:FullColumns="1"
  8.     x:FullRows="1" ss:DefaultColumnWidth="60">
  9.     <Column ss:AutoFitWidth="1"/>
  10.     <Column ss:AutoFitWidth="0" ss:Width="91.5"/>
  11.     <Column ss:AutoFitWidth="0" ss:Width="21.75"/>
  12.     <Column ss:AutoFitWidth="0" ss:Width="168.75"/>
  13.     <Column ss:AutoFitWidth="0" ss:Width="230.25"/>
  14.     <Column ss:AutoFitWidth="0" ss:Width="63.75"/>
  15.     <Column ss:AutoFitWidth="0" ss:Width="74.25"/>
  16.     <Column ss:AutoFitWidth="0" ss:Width="77.25"/>
  17.     <Column ss:Width="113.25"/>
  18.     <Column ss:AutoFitWidth="0" ss:Width="105"/>
  19.     <Column ss:AutoFitWidth="0" ss:Width="67.5"/>
  20.     <Column ss:AutoFitWidth="0" ss:Width="93" ss:Span="2"/>
  21.     <Column ss:Index="15" ss:AutoFitWidth="0" ss:Width="83.25"/>
  22.     <Column ss:AutoFitWidth="0" ss:Width="67.5"/>
  23.     <Column ss:AutoFitWidth="0" ss:Width="93"/>
  24.     <Column ss:AutoFitWidth="0" ss:Width="135" ss:Span="4"/>


 
Mon XSLT :  
 

Code :
  1. <?xml version="1.0" encoding="ISO-8859-1" ?>
  2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  3. xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
  4. <xsl:output method="xml" indent="yes" omit-xml-declaration="no" encoding="ISO-8859-1" />
  5.             <xsl:template match="/">
  6. <EXPORT>
  7. <COMPONENT_FAMILY>
  8. <IDENTIFICATION >
  9.             <xsl:attribute name="NAME">
  10.              <xsl:value-of select="//Worksheet/@ss:Name"/>
  11.             </xsl:attribute>
  12. </IDENTIFICATION>
  13. </COMPONENT_FAMILY>
  14. </EXPORT>


 
Et mon résultat :  

Code :
  1. <EXPORT xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
  2. <COMPONENT_FAMILY>
  3. <IDENTIFICATION NAME="" />
  4. </COMPONENT_FAMILY>
  5. </EXPORT>


 
Mes 2 soucis :  
 
Il me met la déclaration des namespaces dans la balise EXPORT alors que je voudrais que ce ne soit pas dans le résultat.
 
L’attribut NAME de la balise IDENTIFICATION est de valeur vide alors que je voudrait qu’il me renvoie « Composants »
 
Si vous pouviez m'aider car la je patauge complètement ...  
 
Merci  :hello:


Message édité par DelWeb le 04-11-2011 à 15:32:02
Reply

Marsh Posté le 04-11-2011 à 15:31:23   

Reply

Marsh Posté le 04-11-2011 à 16:47:20    

Pour la déclaration du namespace, si on n'en veut pas en sortie: exclude-result-prefixes
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
exclude-result-prefixes="ss" >
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 04-11-2011 à 16:52:46    

Ca marche !!  
Merci :)  
 
Plus qu'un soucis à résoudre :)

Reply

Marsh Posté le 04-11-2011 à 17:36:23    

Je n'ai pas répondu volontairement au second, car c'est quelque chose de tellement basique, que si vous avez potassé un minimum le XSLT, vous saurez comment faire.
Il ne faut peut être pas se moquer du monde, n'importe quel tutorial sur le XSLT vous montre rapidement comment récupérer le valeur d'un attribut pour l'écrire dans le XML résultat.
A+,


Message édité par gilou le 04-11-2011 à 17:41:10

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 07-11-2011 à 13:56:59    

Ce n'était peut être pas la peine d'être aussi sec ...  
 
J'en ai lu beaucoup des tutoriels XSLT et je ne comprend pas pourquoi il ne me renvoie rien ... J'ai essayé plusieurs façon pour extraire la valeur "Composants" et avec Cooktop j'ai toujours un vide dan smon attribut NAME dans le résultat ...  
 
Si vous aviez une piste ça m'arrangerait :)  
 
Merci !

Reply

Marsh Posté le 07-11-2011 à 17:19:19    

Ah désolé, j'avais pensé que vous aviez fait une faute de débutant.
En fait, c'est plus subtil que cela, vous êtes tombée sur le piège standard du namespace par défaut:
1) Dans le document source, vous avez un namespace par défaut
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
Donc quand il y a un élément sans préfixe dans le source, il est envoyé au xslt avec son namespace préfixé, bref, quelquechose comme <Workbook> dans le source est vu par le XSLT comme <{urn:schemas-microsoft-com:office:spreadsheet}Workbook> ou quelque chose dans le genre.
Donc pour que les règles du XSLT s'appliquent a un élément non préfixé du source, il faut
  a) définir un namespace et un préfixe dans le XSLT, avec comme valeur du namespace celle du namespace par défaut du source  
      par exemple xmlns:rt="urn:schemas-microsoft-com:office:spreadsheet"  
  b) Dans les règles XSLT, préfixer avec ce préfixe les noms des éléments sans préfixe dans le source:
      <xsl:value-of select="//rt:Worksheet"/>
2) Dans le XSLT, vous avez un préfixe sur l'attribut: @ss:Name car il y en a un dans le source
    C'est bien, mais ça suffit pas, car le xslt ne prend pas en compte pour lui même les déclarations de namespaces du source
    Il vous faudra donc recopier les déclarations de namespace (sauf celle du namespace par défaut s'il y en a un) dans le XSLT.
 
Bref, ceci devrait faire ce que vous cherchiez.
 

Code :
  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2. <!-- prefixe rt: pour le namespace par défaut du source -->
  3. <xsl:stylesheet version="1.0"  
  4. xmlns:rt="urn:schemas-microsoft-com:office:spreadsheet"  
  5. xmlns:o="urn:schemas-microsoft-com:office:office"  
  6. xmlns:x="urn:schemas-microsoft-com:office:excel"  
  7. xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"  
  8. xmlns:html="http://www.w3.org/TR/REC-html40"  
  9. xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
  10. >
  11. <xsl:output method="xml" indent="yes" omit-xml-declaration="no" encoding="ISO-8859-1" />
  12.            <xsl:template match="/">
  13. <EXPORT>
  14.  <COMPONENT_FAMILY>
  15.    <IDENTIFICATION >
  16.      <xsl:attribute name="NAME">
  17.     <xsl:value-of select="//rt:Worksheet/@ss:Name"/>
  18.      </xsl:attribute>
  19.    </IDENTIFICATION>
  20.  </COMPONENT_FAMILY>
  21. </EXPORT>
  22. </xsl:template>
  23. </xsl:stylesheet>


       
Noter qu'on doit en fait ici simplifier, en virant la déclaration du namespace rt, et en réutilisant le namespace ss.

Code :
  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2. <xsl:stylesheet version="1.0"  
  3. xmlns:o="urn:schemas-microsoft-com:office:office"  
  4. xmlns:x="urn:schemas-microsoft-com:office:excel"  
  5. xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"  
  6. xmlns:html="http://www.w3.org/TR/REC-html40"  
  7. xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
  8. exclude-result-prefixes="ss o x">
  9. <xsl:output method="xml" indent="yes" omit-xml-declaration="no" encoding="ISO-8859-1" />
  10.            <xsl:template match="/">
  11. <EXPORT>
  12.  <COMPONENT_FAMILY>
  13.    <IDENTIFICATION >
  14.      <xsl:attribute name="NAME">
  15.     <xsl:value-of select="//ss:Worksheet/@ss:Name"/>
  16.      </xsl:attribute>
  17.    </IDENTIFICATION>
  18.  </COMPONENT_FAMILY>
  19. </EXPORT>
  20. </xsl:template>
  21. </xsl:stylesheet>


A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 08-11-2011 à 15:12:31    

Merci beaucoup pour ton aide, j'ai appliqué tes conseils et j'ai rajouté le namespace à mes balises <worksheet> au doc source et en recopiant ton XSLT mais ça me sort toujours :  
 

Code :
  1. <EXPORT>
  2. <COMPONENT_FAMILY>
  3. <IDENTIFICATION NAME="" />
  4. </COMPONENT_FAMILY>
  5. </EXPORT>

Reply

Marsh Posté le 08-11-2011 à 20:03:02    

Ben chez moi ça marche comme prévu:
Le XML en entrée: worksheet.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<Workbook  
xmlns="urn:schemas-microsoft-com:office:spreadsheet"  
xmlns:o="urn:schemas-microsoft-com:office:office"  
xmlns:x="urn:schemas-microsoft-com:office:excel"  
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"  
xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet ss:Name="Composants">
   <Table ExpandedColumnCount="22" ExpandedRowCount="3"  
    DefaultColumnWidth="60">
    <Column AutoFitWidth="1"/>
    <Column AutoFitWidth="0" Width="91.5"/>
    <Column AutoFitWidth="0" Width="21.75"/>
    <Column AutoFitWidth="0" Width="168.75"/>
    <Column AutoFitWidth="0" Width="230.25"/>
    <Column AutoFitWidth="0" Width="63.75"/>
    <Column AutoFitWidth="0" Width="74.25"/>
    <Column AutoFitWidth="0" Width="77.25"/>
    <Column Width="113.25"/>
    <Column AutoFitWidth="0" Width="105"/>
    <Column AutoFitWidth="0" Width="67.5"/>
    <Column AutoFitWidth="0" Width="93" Span="2"/>
    <Column Index="15" AutoFitWidth="0" Width="83.25"/>
    <Column AutoFitWidth="0" Width="67.5"/>
    <Column AutoFitWidth="0" Width="93"/>
    <Column AutoFitWidth="0" Width="135" Span="4"/>
  </Table>
</Worksheet>
</Workbook>


Le feuille de style XSLT: worksheet.xsl

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"  
xmlns:o="urn:schemas-microsoft-com:office:office"  
xmlns:x="urn:schemas-microsoft-com:office:excel"  
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"  
xmlns:html="http://www.w3.org/TR/REC-html40"  
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="ss o x">
 
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" encoding="ISO-8859-1" />
            <xsl:template match="/">
<EXPORT>
  <COMPONENT_FAMILY>
    <IDENTIFICATION >
      <xsl:attribute name="NAME">
 <xsl:value-of select="//ss:Worksheet/@ss:Name"/>
      </xsl:attribute>
    </IDENTIFICATION>
  </COMPONENT_FAMILY>
</EXPORT>
</xsl:template>
 
</xsl:stylesheet>


Le processing par un processeur XSLT (Saxon en l’occurrence)

C:\Program Files\Saxonica\SaxonHE9.3N>bin\Transform -t -s:workbook.xml -xsl:workbook.xsl -o:wout.xml
Saxon-HE 9.3.0.5N from Saxonica
.NET 2.0.50727.3625 on Microsoft Windows NT 5.1.2600 Service Pack 3
URIResolver.resolve href="file:/C:/Program%20Files/Saxonica/SaxonHE9.3N/workbook.xsl" base="null"
Using parser org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser
Warning: at xsl:stylesheet on line 9 column 34 of workbook.xsl:
  Running an XSLT 1 stylesheet with an XSLT 2 processor
Stylesheet compilation time: 2359 milliseconds
Processing file:/C:/Program%20Files/Saxonica/SaxonHE9.3N/workbook.xml
Building tree for file:///C:/Program Files/Saxonica/SaxonHE9.3N/workbook.xml using class net.sf.saxon.tree.tiny.TinyBuilder
Tree built in 47 milliseconds
Tree size: 45 nodes, 0 characters, 37 attributes
Execution time: 516ms
Memory used: 2840524
NamePool contents: 28 entries in 28 chains. 10 prefixes, 10 URIs


Le fichier XML obtenu en sortie: wout.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<EXPORT xmlns:html="http://www.w3.org/TR/REC-html40">
   <COMPONENT_FAMILY>
      <IDENTIFICATION NAME="Composants"/>
   </COMPONENT_FAMILY>
</EXPORT>


On voit d'ailleurs que comme je n'avais pas mis html dans la liste des préfixes exclus, le namespace associé figure en sortie.
 
A+,


Message édité par gilou le 08-11-2011 à 20:08:03

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 09-11-2011 à 10:22:51    

Pour ma part j'utilise Cooktop et en lisant ton post précédent, j'ai fouillé un peu et j'ai changé le processeur XSLT pour .NET à la place de MSXML et ça marche !  
 
Merci beaucoup !!

Reply

Marsh Posté le 09-11-2011 à 10:33:34    

Oui pour processer du XSLT, j'ai plutôt tendance a utiliser saxon ( saxon.sourceforge.net ) ou XT ( http://www.blnz.com/xt/index.html ) qui sont des valeurs sures.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed