2017-06-28 2 views
0

Je souhaite convertir un nom/valeur xml en élément xml en utilisant xsl. J'ai essayé toutes les méthodes que j'ai pu trouver. J'ai référé ce poste, Convert Name/Value Pair XML to Elements using XSLT et fait les changements, mais mon xml résultant ne montre pas les valeurs clés.Problème lors de la conversion du nom/de la valeur xml en élément xml en utilisant xsl

Voici mes fichiers de code:

fichier xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 

<METSM xmlns="metsmng" xmlns:ns2="http://www.w3.org/1999/xlink"> 
<Case id="MTMzo29276" ns2:href="https://metsm.com/api/case/MTMzo29276"> 
    <Column name="BU">SU</Column> 
    <Column name="Summary">Hardware failure</Column> 
    <Column name="Project">Servers</Column> 
    <Column name="Priority">High</Column> 
    <Column name="Status">Working</Column> 
    <Column name="Open-Date">01/23/2017 23:11:16</Column> 
</Case> 
<Case id="MTMzo29739" ns2:href="https://metsm.com/api/case/MTMzo29739"> 
    <Column name="BU">AICM</Column> 
    <Column name="Summary">Create a new profile</Column> 
    <Column name="Project">Datacentre</Column> 
    <Column name="Priority">Low</Column> 
    <Column name="Status">Open</Column> 
    <Column name="Open-Date">10/04/2010 00:00:00</Column> 
</Case> 
</METSM> 

xsl:

<?xml version="1.0"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
<xsl:output method="xml" indent="yes"/> 

<xsl:template match="/METSM"> 
<METSM> 
    <xsl:for-each select="Case"> 
    <Case> 
     <xsl:element name="{@id}"> 
     <xsl:value-of select="."/> 
     </xsl:element> 
     <xsl:for-each select="Column"> 
     <xsl:element name="{@name}"> 
      <xsl:value-of select="."/> 
     </xsl:element> 
     </xsl:for-each> 
    </Case> 
</xsl:for-each> 
</METSM> 
</xsl:template> 
</xsl:stylesheet> 

Résultat requis:

<METSM> 
<Case> 
    <id> MTMzo29276 </id> 
    <BU> SU </BU> 
    <Summary> Hardware failure </Summary> 
    .... 
</Case> 
<Case> 
.... 
</Case> 
</METSM> 

Ce que je veux:

<?xml version="1.0" encoding="UTF-8"?> 


    SU 
    Hardware failed 
    Servers 
    High 
    Working 
    01/23/2017 23:11:16 


    AICM 
    Create a new profile 
    Datacentre 
    Low 
    Open 
    10/04/2010 00:00:00 

Je n'arrive pas à comprendre le problème. Comment puis-je obtenir les noms de clés dans mon fichier XML de résultat. Toute aide sera très reconnaissante. Merci d'avance.

EDIT: en utilisant le code ci-dessous python pour générer le fichier xml de sortie:

from lxml import etree 
data = open(r'C:\Users\abc\Desktop\input-xsl.xsl') 
xslt_content = data.read() 
xslt_root = etree.XML(xslt_content) 
dom = etree.parse(r'C:\Users\abc\Desktop\input-xml.xml') 
transform = etree.XSLT(xslt_root) 
result = transform(dom) 
print(result) 

Répondre

0

Il est parce que votre XML est dans l'espace de noms par défaut metsmng. Puisque vous utilisez XSLT 2.0, vous pouvez utiliser xpath-default-namespace ...

XSLT 2,0

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" 
    xpath-default-namespace="metsmng"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/METSM"> 
    <METSM> 
     <xsl:for-each select="Case"> 
     <Case> 
      <id><xsl:value-of select="@id"/></id> 
      <xsl:for-each select="Column"> 
      <xsl:element name="{@name}"> 
       <xsl:value-of select="."/> 
      </xsl:element> 
      </xsl:for-each> 
     </Case> 
     </xsl:for-each> 
    </METSM> 
    </xsl:template> 
</xsl:stylesheet> 

Notez également que je fixe votre sortie de l'élément id.

Sortie

<METSM> 
    <Case> 
     <id>MTMzo29276</id> 
     <BU>SU</BU> 
     <Summary>Hardware failure</Summary> 
     <Project>Servers</Project> 
     <Priority>High</Priority> 
     <Status>Working</Status> 
     <Open-Date>01/23/2017 23:11:16</Open-Date> 
    </Case> 
    <Case> 
     <id>MTMzo29739</id> 
     <BU>AICM</BU> 
     <Summary>Create a new profile</Summary> 
     <Project>Datacentre</Project> 
     <Priority>Low</Priority> 
     <Status>Open</Status> 
     <Open-Date>10/04/2010 00:00:00</Open-Date> 
    </Case> 
</METSM> 

Vous avez mentionné dans les commentaires que vous utilisez lxml. Si oui, XSLT 2.0 n'est pas supporté; vous devrez utiliser XSLT 1.0. Qu'est-ce que vous devez faire est de lier l'espace de noms à un préfixe et utiliser ce préfixe dans vos XPath de ...

XSLT 1,0

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
    xmlns:m="metsmng" exclude-result-prefixes="m"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/m:METSM"> 
    <METSM> 
     <xsl:for-each select="m:Case"> 
     <Case> 
      <id><xsl:value-of select="@id"/></id> 
      <xsl:for-each select="m:Column"> 
      <xsl:element name="{@name}"> 
       <xsl:value-of select="."/> 
      </xsl:element> 
      </xsl:for-each> 
     </Case> 
     </xsl:for-each> 
    </METSM> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Merci Daniel. Mais je ne reçois toujours pas les balises dans mon fichier XML de sortie. Je courais le code ci-dessous en python pour générer mon fichier xml de sortie: de etree import lxml data = open (R'C: \ Users \ anubmand \ Desktop \ input-xsl.xsl ') xslt_content = données .read() = xslt_root etree.XML (xslt_content) dom = etree.parse (R'C: \ Users \ anubmand \ Desktop \ input-xml.xml ') transformer = etree.XSLT (xslt_root) result = transformer (dom) imprimer (résultat) – starFire

+0

@starFire - Um ouais ... lxml ne supporte pas XSLT 2.0. Je vais modifier ma réponse. –

+0

Merci beaucoup. Ça a marché. – starFire