6
votes

Xslt conditionnel include du fichier externe

Je veux effectuer un conditionnel include dans XSLT, mais XSL: Inclure est un élément de niveau supérieur. Vous ne pouvez utiliser que XSL: Si ou XSL: Choisissez à l'intérieur d'un modèle. Y a-t-il une sorte de piratage ou de travail autour qui permet une inclusion conditionnelle d'un fichier externe? J'ai essayé d'utiliser la fonction Document (), mais elle ne charge pas de charger mon fichier externe (probablement parce qu'il ne se conforme pas à un ensemble de règles qui le ferait "valide").

Mon fichier XML externe est un tas de fragments de code XSLT. En fonction de la valeur d'une variable dans le fichier XSLT principal, le code Corisponding du fichier externe doit être "Copier / collé" en place (comme conditionnel include en C ou PHP).

Le flux de mon Le fichier XSLT principal devrait procéder de la manière suivante: xxx

évidemment je ne peux évidemment pas le faire comme ce qui précède, pourquoi je demande s'il y a un piratage ou une solution de contournement.


0 commentaires

8 Réponses :


3
votes

Si je comprends les choses, "inclure" se produit lorsque l'analyseur XML analyse et compose la feuille de style. Cela signifie qu'aucune évaluation logique ou d'expression ne peut arriver avant que l'inclusion ne soit traitée et donc il n'y a aucun moyen de le rendre conditionnel en tant que tel. Vous devez faire durer le comportement conditionnel en dehors de la feuille de style.

Regardez sur ce http://www.dpawson.co .uk / xsl / sect2 / n4760.html # D6065E100

en particulier ce commentaire de Mike Kay aidez-vous:

Ceci a été soulevé plusieurs fois. Sur un thread précédent, nous sommes venus à la conclusion que l'utilisateur essayait d'écrire un usage général stylesheet g et ensuite la spécialiser en conditionnellement inclus la feuille de style spécial a ou B. La voie à suivre cette exigence est avoir A et B inclut g, pas l'inverse, puis vous Sélectionnant conditionnellement A ou B comme étant la feuille de style principale lors du démarrage la transformation.


0 commentaires

6
votes

Ceci ne peut pas être fait avec XSLT 1.0 et peut être effectué (dans une mesure très limitée) dans XSLT 2.0 à l'aide du Utilisez-quand attribut . .

Il existe des moyens non-XSLT d'atteindre la modification dynamique souhaitée d'un XSL: Inclure ou un xsl: importer directive.

une méthode de ces méthodes consiste à charger la feuille de style XSLT en tant que xmldocument et à l'aide des méthodes DOM disponibles pour l'accès et la modification des attributs, pour définir l'attribut href à la valeur souhaitée. Ensuite, lancez la transformation de cette feuille de style XMLDOCument XMLDOCUMUMUMUMUMUME-CONTENU XMLDOCUMTOPLEDOCLED.


0 commentaires

3
votes

Essayez Invertir la structure: Si vous avez deux modules à usage spécial rose.xsl et blue.xsl, et un module à usage général BABY.XSL, puis au lieu d'essayer d'importer / inclure l'une des roses.xsl ou blue.xsl Dans BABY.XSL, utilisez plutôt rose.xsl ou blue.xsl en tant que feuille de style d'entrée de niveau supérieur et chacune de ces deux importations BABY.XSL. C'est comme ça que cela a été conçu pour être utilisé, il est nut un piratage ou une solution de contournement.

Alternativement, compte tenu de cette description de votre scénario "Mon fichier XML externe est un tas de fragments de code XSLT", une meilleure approche dans votre cas peut être d'assembler la feuille de style de ces fragments comme une étape séparée, à l'aide d'une transaction XSLT plutôt. que d'utiliser XSL: Inclure / XSL: importation.


0 commentaires

0
votes

En plus de ce qui a déjà été dit, une solution éventuelle serait de rendre les fichiers supplémentaires à être simples, fournissant des fichiers XML (au lieu de fichiers XSLT). De cette façon, vous pouvez les inclure avec la fonction XPATH () (qui sera évaluée à l'heure d'exécution plutôt que de compiler le temps).

Vous pouvez ensuite modifier le comportement de votre transformation en fonction du contenu du document XML chargé; Cependant, vous ne pouvez pas fournir de fragments XSLT exécutables dans les documents inclus.

Cela dépend de votre utilisation s'il s'agissait d'une solution - si les documents supplémentaires ont un impact important sur le flux de contrôle de votre transformation, vous ne voulez pas les définir dans un XML uni, car vous seriez fondamentalement mettre en œuvre quelque chose comme xslt. Toutefois, lorsque vos documents servent de fichiers de configuration, vous voudrez peut-être penser à leur fournir une ALS PURE XML.

Lorsque vous rencontrez des problèmes avec document () , utilisez un validateur XML sur vos fichiers. Une erreur implique que vos fichiers ne sont pas valides XML.


0 commentaires

0
votes
<xsl:variable name="CONDITIONAL" select="ELEMENT/CONDITION"/>
<xsl:variable name="DOCUMENTNAME" select="document(concat($CONDITIONAL,'-DOCUMENT.xml'))/ELEMENT"/>
This example is how I did a conditional use of an external file.  I had the flag in the base XML that the XSL uses as a variable to help specify the name of the other file to pull into the template. Once that variable is defined as in my case I use it to pull other XML data into the generated output. The concat command forces the data together to give a file name.So When I want info from the external XML file I use '$DOCUMENTNAME' for referencing the external data.

0 commentaires

1
votes

Je ne sais pas si cela s'appliquerait à votre scénario, mais je vais y jeter de toute façon.

J'ai fait des choses similaires dans le passé, mais au lieu de faire une condition conditionnelle, j'appelle un modèle Dans l'un des deux fichiers basé sur ce que le XSL: lorsqu'il est évalué à. Si vous ne voulez pas utiliser de modèles dans votre cas, ignorez cette réponse. P>

Par exemple, disons que le fichier XSLT "parent" est appelé root.xslt strong> et les deux Les utilisées conditionnellement sont enfant1.xslt strong> et enfant2.xslt strong>. Disons que je veux exécuter une logique conditionnelle contre la valeur d'un nœud appelé statut em>. Si la valeur est "actuelle", je veux appeler un modèle appelé Iscurrent em> dans enfant1.xslt, sinon appelez un modèle appelé isnotcurrent em> dans enfant2.xslt. Pour des raisons de brièveté, dans chaque cas, je passe simplement le gabarit le nœud racine et tous les enfants. P>

Il ressemblait à ceci comme suit: P>

<?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:import href="child1.xslt"/>
    <xsl:import href="child2.xslt"/>

    <xsl:template match="/">
      <xsl:choose>
        <xsl:when test="rootNode/status = 'CURRENT'">
          <!-- template isCurrent defined in child1.xslt -->
          <xsl:apply-templates select="rootNode" mode="isCurrent" />
        </xsl:when>
        <xsl:otherwise>
          <!-- template isNotCurrent defined in child2.xslt -->
          <xsl:apply-templates select="rootNode" mode="isNotCurrent" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>
</xsl:stylesheet>


0 commentaires

0
votes

Avec l'ajout de paramètres statiques , ceci est maintenant possible dans XSLT 3.0. Les paramètres statiques peuvent être utilisés dans l'utilisation lorsque code> attribut du xsl: Inclure code>.

Nous pouvons désormais déclarer des paramètres avec des valeurs par défaut de false () puis remplacez ceux dont nous avons besoin au moment de l'exécution ... p> xxx pré>

Voici un exemple de travail complet testé avec Saxon-il v9.7 (également testé avec Saxon-PE 9.5). P>

Entrée XML forte> (test .xml) p>

<doc>
   <foo>INCLUDE FILE 2!!!</foo>
</doc>


0 commentaires

0
votes

Il y a une approche que j'ai constatée pour inclure de manière conditionnelle des fichiers à l'aide de l'utilisation - une fois la fonctionnalité de XSLT 2.0.

Vous devez créer une propriété système qui passe à travers l'application au moment de l'exécution, comme dans mon cas, j'utilise Java J'ai donc créé une propriété "debug" à l'aide de la commande pour exécuter mon application: xxx

puis dans XSLT Utilisez cette propriété pour inclure des fichiers conditionnels. Par exemple xxx

comme ça.

Je ne sais pas s'il convient au scénario demandé mais oui, il existe un moyen de le faire dans XSLT 2.0. Dans XSLT 3.0, la prise en charge de la variable locale est également ajoutée. Cela peut donc être facilement effectué à l'aide de variables locales.

merci, Codage heureux


0 commentaires