2010-12-07 5 views
2

Est-il possible d'accéder à nœud enfant attribue à xsl: ifattribut nœud enfant dans XSLT

Je dois convertir cette Xml en fichier texte

<Report> 
<Total> 
    <RecordValues> 
     <Record> 
     <FieldValue fieldName="index"  fieldValue="1" /> 
     <FieldValue fieldName="dtrk_sysid" fieldValue="0"/> 
     <FieldValue fieldName="version"  fieldValue="100" /> 
     <FieldValue fieldName="user"  fieldValue="tester" /> 
     <FieldValue fieldName="date_modified" fieldValue="2010-10-18 12:18:12" /> 
     <FieldValue fieldName="object_name"  fieldValue="Menu" /> 
     <FieldValue fieldName="permission" fieldValue="Permission X" /> 
     </Record> 
     <Record> 
     <FieldValue fieldName="index"  fieldValue="2" /> 
     <FieldValue fieldName="dtrk_sysid" fieldValue="55555"/> 
     <FieldValue fieldName="version"  fieldValue="100" /> 
     <FieldValue fieldName="user"  fieldValue="user1" /> 
     <FieldValue fieldName="date_modified" fieldValue="2010-12-15 12:18:12" /> 
     <FieldValue fieldName="object_name"  fieldValue="Control" /> 
     <FieldValue fieldName="permission" fieldValue="Permission E" /> 
     </Record> 
     <Record> 
     <FieldValue fieldName="index"  fieldValue="3" /> 
     <FieldValue fieldName="dtrk_sysid" fieldValue="55555"/> 
     <FieldValue fieldName="version"  fieldValue="15" /> 
     <FieldValue fieldName="user"  fieldValue="user2" /> 
     <FieldValue fieldName="date_modified" fieldValue="2010-10-02 12:18:12" /> 
     <FieldValue fieldName="object_name"  fieldValue="Run" /> 
     <FieldValue fieldName="permission" fieldValue="Permission R" /> 
     </Record> 
    </RecordValues> 
</Total> 

Je sais déjà comment pour faire cela, mais le fichier doit avoir un enregistrement en-tête qui doit apparaître une seule fois comme le premier enregistrement du fichier. Il doit contenir certaines valeurs par défaut et certaines valeurs du nœud FieldValue. Voici l'exemple d'en-tête:

HDRTT55555EE000KK20101018UU 
1 100 101810 
tester Menu  Permission X 
2 100 121510 
user1 Control Permission E 
3 15 100210 
user2 Run  Permission R 

Voici ce que je l'ai fait jusqu'à présent:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text" indent="yes" encoding="UTF-8" omit-xml- declaration="yes"/> 

<xsl:template match="/"> 
    <xsl:apply-templates select="/Report/Total/RecordValues"/> 
    <xsl:apply-templates select="/Report/Total/RecordValues/Record/FieldValue"/> 
</xsl:template> 
<xsl:template match="RecordValues"> 
    <xsl:text>HDR</xsl:text> 
    <xsl:text>TT</xsl:text> 
    <xsl:variable name="fvsys" select="Record/FieldValue[@fieldName = 'dtrk_sysid']"/> 
    <xsl:choose> 
     <xsl:when test="$fvsys/@fieldValue != '0'"> 
      <xsl:value-of select="$fvsys/@fieldValue"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:text>12343</xsl:text> 
     </xsl:otherwise> 
    </xsl:choose> 
    <xsl:text>EE</xsl:text> 
    <xsl:text>000</xsl:text> 
    <xsl:text>KK</xsl:text> 
      <xsl:if test="Record/FieldValue[@fieldName='date_modified']"> 
     <xsl:call-template name="ppad"> 
      <xsl:with-param name="str" select="concat(substring(translate(Record/FieldValue[@fieldName = 'date_modified']/@fieldValue,'-',''),5,4), substring(Record/FieldValue[@fieldName = 'date_modified']/@fieldValue,3,2))"/> 
      <xsl:with-param name="len" select="6"/> 
     </xsl:call-template> 
    </xsl:if> 
    <xsl:text>UU</xsl:text> 
    <xsl:text>&#xA;</xsl:text> 
</xsl:template> 

<xsl:template match="FieldValue"> 

</xsl:template> 

<xsl:template name="ppad"> 
    <xsl:param name="str"/> 
    <xsl:param name="chr" select="' '"/> 
    <xsl:param name="len" select="0"/> 
    <xsl:choose> 
     <xsl:when test="string-length($str) &lt; $len"> 
      <xsl:call-template name="ppad"> 
       <xsl:with-param name="str" select="concat($str, $chr)"/> 
       <xsl:with-param name="len" select="$len"/> 
       <xsl:with-param name="chr" select="$chr"/> 
      </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$str"/> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
</xsl:stylesheet> 

Merci pour votre aide.

+1

Oui. Veuillez fournir plus de détails, tels qu'un exemple de document XML et ce que vous avez essayé jusqu'à présent. –

+0

s'il vous plaît fournir la pleine sortie désirée. – Flack

+1

Ce n'est pas clair du tout. Tout d'abord, l'en-tête/le traitement des données dans XSLT implique l'utilisation de modes. Deuxièmement, vous effectuez une comparaison existentielle sur tous les enregistrements: "y at-il ** any **' @ fieldName' égal à "dtrk_sysid" et ** any ** '@ fieldValue' différent de 0?" –

Répondre

4

Le principal problème avec les éléments suivants instruction if:

<xsl:if test="Record/FieldValue/@fieldName='dtrk_sysid' and Record/FieldValue/@fieldValue!='0'"> 
    <xsl:value-of select="Record/FieldValue/@fieldValue"/> 
</xsl:if> 

est que le @fieldValue vous essayez de comparer après la and est censé être le @fieldValue du <FieldValue> dont @fieldName est « dtrk_sysid ', mais il n'y a rien qui limite la deuxième comparaison à ce <FieldValue> particulier. Le <xsl:if test=...> ne définit pas de contexte. <xsl:value-of> va alors sélectionner l'attribut @fieldValue de tous les nœuds Record/FieldValue sous le nœud de contexte, qui par chance est le bon, dans votre XML d'entrée d'échantillon (mais peut-être pas toujours?).

Pour résoudre ce problème, vous pouvez saisir le contexte (la <FieldValue> dont @fieldName est 'dtrk_sysid') dans une variable:

<xsl:variable name="fvsys" select="(Record/FieldValue[@fieldName = 'dtrk_sysid'])[1]"/> 

Ensuite, vous pouvez remplacer vos deux premières déclarations si:

<xsl:choose> 
    <xsl:when test="$fvsys/@fieldValue != '0'"> 
     <xsl:value-of select="$fvsys/@fieldValue"/> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:text>12343</xsl:text> 
    </xsl:otherwise> 
    </xsl:choose> 

(qui précède a été modifié pour adapter le comportement décrit dans les commentaires.)

Vous pouvez remplacer votre troisième instruction if avec:

<xsl:value-of select="(Record/FieldValue[@fieldName = 'date_modified'])[1]/@fieldValue"/> 

Ceci ne produira rien si aucune FieldValue n'existe.

Si après cela, vous n'obtenez toujours pas la sortie désirée, dites-nous quelle sortie vous obtenez, et en quoi elle diffère de la sortie désirée.

+0

@LarsH: Merci de m'avoir aidé. Désolé pour la réponse tardive, était loin de l'ordinateur. Je cours juste un test. Condition dans l'instruction WHEN ne fonctionne pas correctement. Si il renvoie "55555", mais si fieldValue = "0" il renvoie "0". Donc, ça ne va pas à défaut. – klipa

+0

@klipa, essayez de changer '! = 0' en'! = '0'', comme vous l'aviez à l'origine. – LarsH

+0

@LarsH, j'ai essayé ça aussi, mais le résultat est le même. – klipa

Questions connexes