1
votes

XSLT - Valeur de recherche d'une autre partie de xml à l'intérieur de foreach

J'ai le XML suivant.

<?xml version="1.0"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:l="http://1.local/1.xsd"
  exclude-result-prefixes="l"
  version="1.0">
  <xsl:output method="text" omit-xml-declaration="yes" media-type="text/plain" />

  <xsl:template match="/">
    <xsl:apply-templates select="l:Root/l:Files" />
  </xsl:template>

  <xsl:template match="l:Root/l:Files">
    Why
    <xsl:for-each select="l:File">
          File name: <xsl:value-of select="@Name">
          File type:
      </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

Pour chaque fichier, je dois obtenir son attribut Name et pour sa recherche FileTypeID le nom du type de fichier correspondant

Donc, sortie d'exemple serait: Nom de fichier: File1 Type de fichier: FileType1

Nom de fichier: File2 Type de fichier: FileType1

Nom de fichier: File3 Type de fichier: FileType2

Ceci est XSLT que j'ai jusqu'à présent, mais je ne sais pas comment rechercher le nom du type de fichier.

<?xml version="1.0" ?>
<Root xmlns="http://1.local/1.xsd">
    <Definitions>
        <FileTypes>
            <FileType ID="1" Name="FileType1"/>
            <FileType ID="2" Name="FileType2"/>
            <!--... - lots of file types-->
        <FileTypes>
    </Definitions>
    <Files>
        <File Name="File1" FileTypeID="1" />
        <File Name="File2" FileTypeID="1" />
        <File Name="File3" FileTypeID="2" />
        <!--... - lots of files-->
    <Files>
</Root>


0 commentaires

3 Réponses :


2
votes

Utilisez une xsl: key ici pour rechercher les FileTypes

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:l="http://1.local/1.xsd"
  exclude-result-prefixes="l"
  version="1.0">
  <xsl:output method="text" omit-xml-declaration="yes" media-type="text/plain" />

  <xsl:key name="FileTypes" match="l:FileType" use="@ID" />

  <xsl:template match="/">
    <xsl:apply-templates select="l:Root/l:Files" />
  </xsl:template>

  <xsl:template match="l:Files">
    <xsl:for-each select="l:File">
          File name: <xsl:value-of select="@Name" />
          File type: <xsl:value-of select="key('FileTypes', @FileTypeID)/@Name" />
      </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

Ensuite, pour obtenir le nom FileType approprié, vous devez le faire

XXX

Essayez ce XSLT

<xsl:value-of select="key('FileTypes', @FileTypeID)/@Name" />

(Notez que votre XML n'est pas bien formé, car vous n'avez pas de balises de fermeture correctes pour FileTypes et Files.)


0 commentaires

2
votes

Si vous souhaitez travailler avec XSLT, vous devez commencer par comprendre son langage d'expression XPath pour parcourir les arborescences XML, vous pouvez sélectionner // l: FileType [@ID = current () / @ FileTypeID] / @ Name . Ou dans XSLT, comme Tim l'a déjà publié, vous pouvez utiliser une clé pour implémenter efficacement la recherche.


0 commentaires

1
votes

Vous pouvez essayer le XSL suivant.

<Root xmlns="http://1.local/1.xsd">
    <Definitions>
        <FileTypes>
            <FileType ID="1" Name="FileType1"/>
            <FileType ID="2" Name="FileType2"/>
            <!--... - lots of file types-->
        </FileTypes>
    </Definitions>
    <Files>
        <File Name="File1" FileTypeID="1" />
        <File Name="File2" FileTypeID="1" />
        <File Name="File3" FileTypeID="2" />
        <!--... - lots of files-->
    </Files>
</Root>

De plus, vous devez vous assurer que vous avez mis le bon espace de noms dans votre transformation xsl pour qu'il corresponde réellement aux valeurs de votre XML, et il vous manquait quelques balises proches dans votre XML.

Pour être complet, j'ai inclus le XML fixe que j'ai utilisé pour la solution

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:l="http://1.local/1.xsd"
  exclude-result-prefixes="l"
  version="1.0">
  <xsl:output method="text" omit-xml-declaration="yes" media-type="text/plain" />

  <xsl:template match="/">
    <xsl:apply-templates select="l:Root/l:Files" />
  </xsl:template>

  <xsl:template match="l:Root/l:Files">

    Why
    <xsl:for-each select="l:File">
          File name: <xsl:value-of select="@Name"/>
          File type: <xsl:value-of select="//l:FileTypes/l:FileType[@ID=current()/@FileTypeID]/@Name"/>
      </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>


1 commentaires

Ajusté ceci pour refléter la réponse de Martin, car il n'y a pas besoin de la variable que j'ai utilisée.