除了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>
答案 0 :(得分:2)
当前接受的答案有一个漏洞:每当data
的属性与data
的子元素同名时,将始终执行排序使用属性值作为键。而且,它太长了。
此解决方案解决了问题(并且更短),允许指定排序是应该通过attribute-name还是通过element-name:
<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文档上再次应用转换。这次我们通过child- 元素 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>
<强>解释强>:
为了区分我们是要按元素子属性还是按属性排序,我们使用elem!someName
表示排序必须由名为{{1}的子元素的值进行排序的约定}。同样,someName
表示排序必须是名为attrib!someName
的属性的值。
相应地修改someName
insruction以正确选择属性或子元素作为键。不允许存在歧义,因为<xsl:sort>
参数的起始子字符串现在唯一地标识密钥应该是属性还是子元素。
答案 1 :(得分:1)
是的,我很抱歉没有注意到你也希望按属性排序。另请注意,您已更改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>
答案 2 :(得分: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参数的值)
问题是排序值节点选择只是匹配元素(*
仅匹配元素)。