1

除了 ctrlname 列,我得到了一切工作(感谢 empo)。我不太了解语法。我想要做的是使用 xslt 按列名对 gridview 中的 xml 进行排序。一切正常,但 ctrlname 列。如何将属性传递给 XSLT?我试过了:@name、Data/@name、Data[@name]、ctrlname。没有任何效果。

    XmlDataSource1.EnableCaching = False
    Dim xslTrnsform As System.Xml.Xsl.XsltArgumentList = New System.Xml.Xsl.XsltArgumentList
    xslTrnsform.AddParam("sortby", "", sortAttr)
    xslTrnsform.AddParam("orderas", "", orderby)
    XmlDataSource1.TransformArgumentList = xslTrnsform
    XmlDataSource1.DataFile = "~/App_LocalResources/DST_Test.xml"
    XmlDataSource1.XPath = "//data"
    XmlDataSource1.TransformFile = xsltFileName
    'XmlDataSource1.DataBind()
    GridView1.DataSource = XmlDataSource1
    GridView1.DataBind()

XSL

<?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]" data-type="text" order="{$orderas}"/>
            </xsl:apply-templates>
        </root>
    </xsl:template>
    <xsl:template match="data">
        <data>
            <xsl:attribute name="ctrlname">
                <xsl:value-of select="@name"/>
            </xsl:attribute>
            <xsl:attribute name="value">
                <xsl:value-of select="value" />
            </xsl:attribute>
            <xsl:attribute name="comment">
                <xsl:value-of select="comment" />
            </xsl:attribute>
        </data>
    </xsl:template>
</xsl:stylesheet>

XML 输入

<?xml version="1.0" encoding="utf-8" ?>
<root>
    <data name="Test1.Text" xml:space="preserve">
        <value>Please Pick Bare Pump</value>
        <comment>Tab - Pump Configuration</comment>
    </data>
    <data name="Test2.Text" xml:space="preserve">
        <value>Complete</value>
        <comment>A07</comment>
    </data>
    <data name="Test3.Text" xml:space="preserve">
        <value>Confirmed</value>
        <comment>A01</comment>
    </data>
</root>
4

3 回答 3

2

当前接受的答案有一个缺陷:每当有一个data与 的子元素同名的属性时data,将始终使用该属性的值作为键来执行排序。此外,它太长了。

此解决方案解决了允许指定排序是按属性名还是按元素名的问题(并且更短):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="sortby" select="'attrib!name'"/>
    <xsl:param name="orderas" select="'ascending'"/>
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="root">
        <root>
            <xsl:apply-templates select="data">
                <xsl:sort select=
                "*[name()=substring-after($sortby, 'elem!')]
                |
                 @*[name()=substring-after($sortby, 'attrib!')]"
                data-type="text" order="{$orderas}"/>
            </xsl:apply-templates>
        </root>
    </xsl:template>
    <xsl:template match="data">
        <data ctrlname="{@name}" value="{value}"
              comment="{comment}"/>
    </xsl:template>
</xsl:stylesheet>

当应用于此 XML 文档时(基于提供的文档,但更有趣一点):

<root>
    <data name="Test3.Text" xml:space="preserve">
        <value>Please Pick Bare Pump</value>
        <comment>Tab - Pump Configuration</comment>
        <name>X</name>
    </data>
    <data name="Test2.Text" xml:space="preserve">
        <value>Complete</value>
        <comment>A07</comment>
        <name>Z</name>
    </data>
    <data name="Test1.Text" xml:space="preserve">
        <value>Confirmed</value>
        <comment>A01</comment>
        <name>Y</name>
    </data>
</root>

产生正确的结果(按name属性排序)

<root>
   <data ctrlname="Test1.Text" value="Confirmed" comment="A01"/>
   <data ctrlname="Test2.Text" value="Complete" comment="A07"/>
   <data ctrlname="Test3.Text" value="Please Pick Bare Pump" comment="Tab - Pump Configuration"/>
</root>

现在,将 替换<xsl:param name="sortby" select="'attrib!name'"/>

<xsl:param name="sortby" select="'elem!name'"/>

并在同一个 XML 文档上再次应用转换。这次我们得到了按子元素 name的值正确排序的结果:

<root>
   <data ctrlname="Test3.Text" value="Please Pick Bare Pump" comment="Tab - Pump Configuration"/>
   <data ctrlname="Test1.Text" value="Confirmed" comment="A01"/>
   <data ctrlname="Test2.Text" value="Complete" comment="A07"/>
</root>

说明

  1. 为了区分我们是要按子元素排序还是按属性elem!someName排序,我们使用约定必须按名为的子元素的值进行排序someName。类似地,attrib!someName表示必须按名为 的属性的值进行排序someName

  2. 相应地修改指令以<xsl:sort>正确选择属性或子元素作为键。不允许有歧义,因为sortby参数的起始子字符串现在唯一地标识键应该是属性还是子元素。

于 2011-05-19T04:13:41.217 回答
1

是的,很抱歉没有注意到您还想要按属性排序。另请注意,您已经更改了 of 的语法,xsl:param并且以这种方式不正确。将单引号放在双引号内非常重要。这是最终模板:

<?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" select="'value'"/>
        <xsl:param name="orderas" select="'ascending'"/>

    <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="ctrlname">
                <xsl:value-of select="@name"/>
            </xsl:attribute>
            <xsl:attribute name="value">
                <xsl:value-of select="value" />
            </xsl:attribute>
            <xsl:attribute name="comment">
                <xsl:value-of select="comment" />
            </xsl:attribute>
        </data>
    </xsl:template>
</xsl:stylesheet>
于 2011-05-18T19:58:46.383 回答
0

好的,我认为这应该对您有用,允许您在 $sortby 参数中指定属性或元素名称:

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

(您只需传入“name”作为 $sortby 参数的值)

问题是排序值节点选择仅匹配元素(仅匹配元素*)。

于 2011-05-18T19:46:23.623 回答