• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 666
  • Last Modified:

XSL:Sort with dynamic xpath not working

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>
0
gcmachel
Asked:
gcmachel
  • 4
  • 3
1 Solution
 
Geert BormansInformation ArchitectCommented:
<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
0
 
gcmachelAuthor 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.
0
 
Geert BormansInformation ArchitectCommented:
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
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
gcmachelAuthor 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.
0
 
Geert BormansInformation ArchitectCommented:
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
0
 
gcmachelAuthor 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.
0
 
Geert BormansInformation ArchitectCommented:
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
0

Featured Post

[Webinar] Improve your customer journey

A positive customer journey is important in attracting and retaining business. To improve this experience, you can use Google Maps APIs to increase checkout conversions, boost user engagement, and optimize order fulfillment. Learn how in this webinar presented by Dito.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now