开发者

How do I filter data by attribute using XSLT?

开发者 https://www.devze.com 2023-04-04 07:23 出处:网络
How do I only pullnodes that have name that begin with \"tag\" and end with \"DescRes\"? I am using a XMLDataSource and GridView (ASP.NET 3.5) to display the XML. Nothing fancy. If values need to be h

How do I only pull nodes that have name that begin with "tag" and end with "DescRes"? I am using a XMLDataSource and GridView (ASP.NET 3.5) to display the XML. Nothing fancy. If values need to be hard-coded in the XSLT, that's fine too.

<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>开发者_如何学Python;
</data>

If I start with this XML, I'd like the resultant XML after the XSLT is applied to show:

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

Here is my 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>


In XSLT 2.0 use the standard XPath functions starts-with() and ends-with().

In Xpath 1.0 there isn't a function ends-with() so you need to use an equivalent XPath 1.0 expression.

I. XPath 1.0 / XSLT 1.0 solution:

<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>

when applied on the provided XML fragment (made a well-formed XML document by wrapping it into a single top element):

<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>

produces the wanted, correct result:

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

Explanation: The XPath 1.0 equivalent of ends-with($s, $end) is this:

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>

Here we use the Xpath 2.0 standard function ends-with()

0

精彩评论

暂无评论...
验证码 换一张
取 消