سؤال

حصلت على كل شيء يعمل (شكرا empo) باستثناء عمود ctrlname.أنا لا أعرف بناء الجملة جيدا بما فيه الكفاية.ما أحاول القيام به هو استخدام XSLT لفرز XML في GridView بواسطة اسم العمود.كل شيء يعمل ولكن عمود Ctrlname.كيف يمكنني اجتياز سمة إلى XSLT؟لقد حاولت: name، البيانات / الاسم، البيانات، البيانات [اسم]، Ctrlname.لا شيء يعمل. giveacodicetagpre.

xsl giveacodicetagpre.

إدخال XML giveacodicetagpre.

هل كانت مفيدة؟

المحلول

Yes, I'm sorry didnt notice that you wanted also sort by attributes. Note also that you have changed the syntax of xsl:param and it's not correct in that way. It's very important that you keep the single quotes inside the double ones. Here is the final template:

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

نصائح أخرى

The currently accepted answer has one flaw: Whenever there is an attribute of data with the same name as a child element of data, the sort will always be performed using as keys the values of the attribute. Also, it is too long.

This solution solves the problem (and is shorter) allowing to specify whether the sort should be by attribute-name or by 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>

When applied on this XML document (based on the provided one, but made a little-bit more interesting):

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

the correct result (sorted by the name attribute) is produced:

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

Now, replace the <xsl:param name="sortby" select="'attrib!name'"/> with:

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

and apply the transformation again on the same XML document. This time we get the result correctly sorted by the values of the child-element 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>

Explanation:

  1. To distinguish whether we want to sort by an element-child or by an attribute, we use the convention that elem!someName means the sort must be by the values of a child element named someName. Similarly, attrib!someName means the sort must be by the values of an attribute named someName.

  2. The <xsl:sort> insruction is modified accordingly to select as key correctly either an attribute or a child element. No ambiguity is allowed, because the starting substring of the sortby parameter now uniquely identifies whether the key should be an attribute or a child element.

OK, I think this should work for you, allowing you to specify either attribute or element names in the $sortby parameter:

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

(you would just pass in "name" as the value of the $sortby parameter)

The problem was that the sort value node selection was only matching elements (* matches elements only).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top