We help IT Professionals succeed at work.

XSL:Sort with dynamic xpath not working

Medium Priority
690 Views
Last Modified: 2013-11-18
Hi,
Again a same problem with xpath not working with xsl:sort on a dynamic expression. extract of the code is posted here.
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns1="http://www.example.org"
                exclude-result-prefixes="xsl ns1 xsd xref xp20 bpws ora ehdr orcl ids hwf">
               
                <xsl:param name="SortCondition1" select="ns1:last" />
                 <xsl:variable name="SC">
                  <xsl:value-of select="$SortCondition1" />
                </xsl:variable>

  <xsl:template match="/">
    <ns1:employees>
      <xsl:for-each select="//ns1:employees/ns1:employee">
      <xsl:sort select="*[name()=$SC]" order="descending"/>
        <ns1:employee>
          <ns1:first>
            <xsl:value-of select="ns1:first"/>
          </ns1:first>
          <ns1:last>
            <xsl:value-of select="ns1:last"/>
          </ns1:last>
          <ns1:salary>
            <xsl:value-of select="ns1:salary"/>
          </ns1:salary>
        </ns1:employee>
      </xsl:for-each>
    </ns1:employees>
  </xsl:template>
</xsl:stylesheet>

Input XML
-----------

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header/>
    <soap:Body xmlns:ns1="http://www.example.org">
        <ns1:employees>
            <ns1:employee>
                <ns1:first>asd</ns1:first>
                <ns1:last>asd</ns1:last>
                <ns1:salary>123.45</ns1:salary>
            </ns1:employee>
            <ns1:employee>
                <ns1:first>zxc</ns1:first>
                <ns1:last>zxc</ns1:last>
                <ns1:salary>1723.45</ns1:salary>
            </ns1:employee>
        </ns1:employees>
    </soap:Body>
</soap:Envelope>
Comment
Watch Question

Gertone (Geert Bormans)Information Architect
CERTIFIED EXPERT
Top Expert 2006

Commented:
<xsl:param name="SortCondition1" select="ns1:last" />

the problem is that you are not using ns1:last as a literal string,
but as the node with that name
I suppose you want to use the string value,
then you should add single quotes around it

<xsl:param name="SortCondition1" select="'ns1:last'" />

cheers

Geert

Author

Commented:
Hi Gertone,

The value for the SortCondition1 param will be populated dynamically.

means another application passes the value for the SortCondition1...it will not have default value.

Regards - G.
Information Architect
CERTIFIED EXPERT
Top Expert 2006
Commented:
Hi G.,

Then you should have a careful look at the process that passes in the parameter
I have tested your XSLT and it works fine, including the dynamic sorting

you could by the way simplify your tylesheet

    <xsl:template match="/">
        <ns1:employees>
            <xsl:for-each select="//ns1:employees/ns1:employee">
                <xsl:sort select="*[name()=$SC]" order="descending"/>
                    <xsl:copy-of select="."/>
            </xsl:for-each>
        </ns1:employees>
    </xsl:template>

cheers

Geert

Author

Commented:
Hi Gertone,
This is what i tested and the results are posted. Let me know what is the problem and why its not sorting.
xsl
------
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns1="http://www.example.org">
               
                <xsl:param name="SortCondition1" select="ns1:last" />
                 <xsl:variable name="SC">
                  <xsl:value-of select="$SortCondition1" />
                </xsl:variable>

<xsl:template match="/">
        <ns1:employees>
            <xsl:for-each select="//ns1:employees/ns1:employee">
                <xsl:sort select="*[name()=$SC]" order="descending"/>
                    <xsl:copy-of select="."/>
            </xsl:for-each>
        </ns1:employees>
    </xsl:template>


</xsl:stylesheet>

xml
--------
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header/>
    <soap:Body xmlns:ns1="http://www.example.org">
        <ns1:employees>
            <ns1:employee>
                <ns1:first>asd</ns1:first>
                <ns1:last>asd</ns1:last>
                <ns1:salary>123.45</ns1:salary>
            </ns1:employee>
            <ns1:employee>
                <ns1:first>zxc</ns1:first>
                <ns1:last>zxc</ns1:last>
                <ns1:salary>1723.45</ns1:salary>
            </ns1:employee>
        </ns1:employees>
    </soap:Body>
</soap:Envelope>

Output
--------
<?xml version="1.0" encoding="UTF-8"?>
<ns1:employees xmlns:ns1="http://www.example.org">
      <ns1:employee xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
            <ns1:first>asd</ns1:first>
            <ns1:last>asd</ns1:last>
            <ns1:salary>123.45</ns1:salary>
      </ns1:employee>
      <ns1:employee xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
            <ns1:first>zxc</ns1:first>
            <ns1:last>zxc</ns1:last>
            <ns1:salary>1723.45</ns1:salary>
      </ns1:employee>
</ns1:employees>

See the sort is not happening in output and it should get sorted by last name. Not sure why is it happening like this.
Regards,G.
Gertone (Geert Bormans)Information Architect
CERTIFIED EXPERT
Top Expert 2006

Commented:
The code as such is OK.
The problem is in your default value for the parameter
It is accessing a node, it should be a string, so you need to add an extra pair of single quotes around the  ns1:last
like this
    <xsl:param name="SortCondition1" select="'ns1:last'" />

If it doesn't work, when you pass in the parameter,
you need to verify whether the pass-in was done correctly

Author

Commented:
Gertone,
You are correct, This parameter i am passing just for us to test it. But actually the value is passed from a BPEL program which will pass just ns1:last alone. so what would be your suggestion in this place. The actual lines in my XSL would be some thing like this <xsl:param name="SortCondition1" />

What should i do here? should i manually add two quotes around? I tried it that too doesnt work. any suggestions?
Regards,G.
Gertone (Geert Bormans)Information Architect
CERTIFIED EXPERT
Top Expert 2006

Commented:
if it is passed from a BPEL program,
the string passed in will be interpreted as a string, not an XPath expression,
so you should be safe in that regard.
I assume that the value is not really caught.
Can you output the param with a value-of somewhere in your XSLT, maybe between [[ ]], so it is obvious
so you can see what you are actually passing

Explore More ContentExplore courses, solutions, and other research materials related to this topic.