2017-07-15 1 views
0

im coincé avec ce problème.Comment accéder à l'enfant d'un noeud avec un nom de noeud dynamique dans XSLT

Je cette XML:

<Document> 
    <Type>ABC</Type> 
    <Header> 
    <Date>15-01-2017</Date> 
    <Time>11:00 AM</Time> 
    </Header> 
    <Body> 
    <Name>Juan</Name> 
    <Age>10</Age> 
    <Address> 
     <City>City</City> 
     <Country>Country</Country> 
     <Block>Block</Block> 
    </Address> 
    </Body> 
</Document> 

Et je cette XSLT:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" 
> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:variable name ="DocumentType" select ="//Document/Type" /> 

    <xsl:template match ="Document"> 
    <Root> 
     <xsl:apply-templates select ="Header" /> 
     <xsl:element name="Data{$DocumentType}"> 
     <xsl:call-template name="Data"> 
      <xsl:with-param name="type" select ="$DocumentType" /> 
     </xsl:call-template> 
     </xsl:element> 
    </Root> 
    </xsl:template> 

    <xsl:template name ="Data"> 
    <xsl:param name="type" /> 
    <Name> 
     <xsl:value-of select ="Body/Name" /> 
    </Name> 
    <Age> 
     <xsl:value-of select ="Body/Age" /> 
    </Age> 
    <xsl:element name="Address{$type}"> 
     <City> 
     <xsl:value-of select ="City"/> 
     </City> 
     <Country> 
     <xsl:value-of select ="Country"/> 
     </Country> 
     <Block> 
     <xsl:value-of select ="Block"/> 
     </Block> 
    </xsl:element> 
    </xsl:template> 

    <xsl:template match ="Header"> 
    <Header> 
     <DateCreated> 
     <xsl:value-of select ="Date"/> 
     </DateCreated> 
     <TimeCreated> 
     <xsl:value-of select ="Time"/> 
     </TimeCreated> 
    </Header> 
    </xsl:template> 
    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 

mon problème est que je ne peux pas accéder aux valeurs du nœud enfant de l'adresse dans le fichier XML, Je vois seulement ceci:

<Root> 
    <Header> 
    <DateCreated>15-01-2017</DateCreated> 
    <TimeCreated>11:00 AM</TimeCreated> 
    </Header> 
    <DataABC> 
    <Name>Juan</Name> 
    <Age>10</Age> 
    <AddressABC> 
     <City></City> 
     <Country></Country> 
     <Block></Block> 
    </AddressABC> 
    </DataABC> 
</Root> 

Quelqu'un peut-il m'aider à me montrer mon erreur.

Merci

+0

Je suis étonné de savoir pourquoi vous appliquez des modèles à 'Header', mais choisissez d'appeler un modèle nommé pour gérer' Body'. Et bien sûr, le modèle de transformation d'identité ajouté à la fin ne fait rien. –

Répondre

1

Votre erreur a déjà été soulignée dans la réponse de Michael Kay.

Je voulais proposer une autre approche - qui nécessite beaucoup moins de travail:

XSLT 1,0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:variable name="DocumentType" select="/Document/Type" /> 

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

<xsl:template match="/Document"> 
    <Root> 
     <xsl:apply-templates select="Header | Body"/> 
    </Root> 
</xsl:template> 

<xsl:template match="Body"> 
    <xsl:element name="Data{$DocumentType}"> 
     <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="Date | Time"> 
    <xsl:element name="{name()}Created"> 
     <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="Address"> 
    <xsl:element name="Address{$DocumentType}"> 
     <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 

</xsl:stylesheet> 

Notez qu'une variable globale est accessible à partir de tout modèle et ne pas besoin d'être envoyé en paramètre.

+0

est-il possible d'utiliser une chaîne comme "Address {$ DocumentType}" comme nom de modèle ou de correspondance? parce que je pourrais avoir besoin d'un tempat comme ça – zyberjock

+0

https://stackoverflow.com/questions/45108406/need-to-replace-a-value-in-the-match-part-of-xslt#comment77188621_45108406 Je ne sais pas comment Cela concerne votre question ci-dessus. –

1

Tout comme vous utilisez Body/Name pour obtenir le nom, vous pouvez utiliser Body/Address/City pour obtenir la ville (parce que l'élément de contexte est l'élément Document).

Cependant, votre code est un peu monolithique. Faire un xsl:apply-templates sur l'élément d'adresse pourrait être mieux, puis une règle de modèle avec match="Address", dans lequel vous pouvez utiliser select="City" pour sélectionner le City par rapport au Address.