2011-09-09 3 views
3

Comment est-ce que je ne tire que les nœuds qui ont nom qui commencent par "tag" et se terminent par "DescRes"? J'utilise XMLDataSource et GridView (ASP.NET 3.5) pour afficher le XML. Rien d'extraordinaire. Si les valeurs doivent être codées en dur dans le XSLT, c'est bien aussi.Comment filtrer les données par attribut en utilisant XSLT?

<data name="tagoneCtrlNumberRes.Text" xml:space="preserve"> 
    <value>1.</value> 
    <comment>A01</comment> 
</data> 
<data name="tagoneCtrlDescRes.Text" xml:space="preserve"> 
    <value>Hello</value> 
    <comment>A01</comment> 
</data> 
<data name="tagoneCtrlNoteRes.Text" xml:space="preserve"> 
    <value>Hi</value> 
    <comment>A01</comment> 
</data> 

Si je commence avec ce XML, je voudrais que le XML résultant après le XSLT est appliqué à montrer:

<data name="tagoneCtrlDescRes.Text" xml:space="preserve"> 
    <value>Hello</value> 
    <comment>A01</comment> 
</data> 

Voici mon 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:param name="sortby"></xsl:param> 
    <xsl:param name="orderas"></xsl:param> 

    <xsl:output method="xml" indent="yes"/> 

    <!--<xsl:template match="@* | node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()"/> 
     </xsl:copy> 
    </xsl:template>--> 
    <xsl:template match="root"> 
     <root> 
      <xsl:apply-templates select="data"> 
       <xsl:sort select="*[name()=$sortby]|@*[name()=$sortby]" data-type="text" order="{$orderas}"/> 
      </xsl:apply-templates> 
     </root> 
    </xsl:template> 
    <xsl:template match="data"> 
     <data> 
      <xsl:attribute name="comment"> 
       <xsl:value-of select="comment" /> 
      </xsl:attribute> 
      <xsl:attribute name="ctrlname"> 
       <xsl:value-of select="@name"/> 
      </xsl:attribute> 
      <xsl:attribute name="value"> 
       <xsl:value-of select="value" /> 
      </xsl:attribute>    
     </data> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Bonne question, +1. Voir ma réponse pour une solution d'expression XPath 1.0 d'une ligne et sa vérification complète basée sur XSLT 1.0. Une explication détaillée est fournie. –

Répondre

7

Dans XSLT 2.0 utiliser les fonctions XPath standard starts-with() et ends-with().

Dans Xpath 1.0, il n'existe pas de fonction ends-with(), vous devez donc utiliser une expression XPath 1.0 équivalente.

I. solution XPath 1.0/XSLT 1.0:

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

<xsl:template match="/"> 
    <xsl:copy-of select= 
    "*/data[@name[starts-with(.,'tag') 
       and 
       substring(., string-length(.)-11) = 'DescRes.Text' 
       ] 
     ] 
    "/> 
</xsl:template> 
</xsl:stylesheet> 

lorsqu'il est appliqué sur le fragment XML fourni (fait d'un document XML bien formé en l'enveloppant dans un seul élément supérieur):

<t> 
    <data name="tagoneCtrlNumberRes.Text" xml:space="preserve"> 
     <value>1.</value> 
     <comment>A01</comment> 
    </data> 
    <data name="tagoneCtrlDescRes.Text" xml:space="preserve"> 
     <value>Hello</value> 
     <comment>A01</comment> 
    </data> 
    <data name="tagoneCtrlNoteRes.Text" xml:space="preserve"> 
     <value>Hi</value> 
     <comment>A01</comment> 
    </data> 
</t> 

produit le résultat souhaité, correct:

<data name="tagoneCtrlDescRes.Text" xml:space="preserve"> 
     <value>Hello</value> 
     <comment>A01</comment> 
    </data> 

Explication: L'équivalent de 1,0 XPath ends-with($s, $end) est la suivante:

substring($s, string-length($s) - string-length($end) +1) = $end 

II. XPath 2.0/XSLT 2.0 solution:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/"> 
    <xsl:sequence select= 
    "*/data[@name[starts-with(.,'tag') 
       and 
       ends-with(.,'DescRes.Text') 
       ] 
     ] 
    "/> 
</xsl:template> 
</xsl:stylesheet> 

Ici, nous utilisons la fonction standard XPath 2.0 ends-with()

+0

Une seule question. Est-ce que ce doit être dans ce format exact? J'espérais l'adapter à ce que j'ai déjà. En ce moment, j'ai les attributs mappés dans mon XSLT à mon GridView. – dotnetN00b

+1

@ dotnetN00b: Aucune solution n'est absolue et la plupart des solutions à SO tout en résolvant un problème d'une manière spécifique, peuvent être réutilisées/adaptées dans/à une classe de problèmes similaires. Dans ce cas particulier, vous pouvez réutiliser les connaissances acquises dans n'importe quel scénario demandant 'ends-with()'. Bien sûr, vous devez avoir au moins une connaissance de base de XPath et ceci est vrai pour tout langage de programmation dans lequel vous avez trouvé une solution. –

+0

Assez juste. Au moins, j'ai une base à partir de laquelle travailler. Merci, Dimitre. – dotnetN00b

Questions connexes