当前位置 : 主页 > 网页制作 > xml >

xml – 如何使用XSLT按属性过滤数据?

来源:互联网 收集:自由互联 发布时间:2021-06-13
如何仅提取名称以“tag”开头并以“DescRes”结尾的节点?我使用 XMLDataSource和GridView(ASP.NET 3.5)来显示XML.没有什么花哨.如果值需要在XSLT中进行硬编码,那也没关系. data name="tagoneCtrlNumber
如何仅提取名称以“tag”开头并以“DescRes”结尾的节点?我使用 XMLDataSource和GridView(ASP.NET 3.5)来显示XML.没有什么花哨.如果值需要在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>

如果我从这个XML开始,我希望在应用XSLT后显示的结果XML:

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

这是我的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>
在XSLT 2.0中,使用标准XPath函数 starts-with()ends-with().

在Xpath 1.0中,没有函数ends-with(),因此您需要使用等效的XPath 1.0表达式.

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

当应用于提供的XML片段时(通过将其包装到单个顶部元素中,形成格式良好的XML文档):

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

产生想要的,正确的结果:

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

说明:XPath 1.0等价的ends-with($s,$end)是这样的:

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

II. XPath 2.0 / XSLT 2.0解决方案:

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

这里我们使用Xpath 2.0标准函数ends-with()

网友评论