Re: [xsl] xslt sort dilemna

Subject: Re: [xsl] xslt sort dilemna
From: "Mohit Anchlia" <mohitanchlia@xxxxxxxxx>
Date: Wed, 10 Sep 2008 12:55:03 -0700
Thanks for looking at it:
- You are right that's a odd behaviour but that's the business logic.
That actually means is that if State is not PENDING or SUCCEDED then
it's in Error and we just want to return error from one document.
- Please consider filingType as filing element, that's typo on my part.
- Earlier I thought sort would be applied on the output i.e before you
gave detailed explanation of how sort works. As you can see in my XSL
I convert "State" to a number and I really wanted to sort the data
based on the number and not on the character, that is after call to
xsl:apply-templates. Is there any other alternative method to do this.
As I now understand how sort works, I am not sure how I can get what I
want.

Please let me know if I didn't explain properly and thanks for explanation.
On Wed, Sep 10, 2008 at 12:02 PM, Michael Kay <mike@xxxxxxxxxxxx> wrote:
>
> Let's start with the top-level template - there's no point in fixing the
> detail until the top level is right.
>
> <xsl:template match="/">
>   <xsl:choose>
>    <xsl:when test="not(//State='PENDING')
>                and not(//State='SUCCEDED')">
>       <ret>
>          <xsl:copy-of select="//ret/*" />
>       </ret>
>    </xsl:when>
>    <xsl:when test="not($file2//State='PENDING')
>                and not($file2//State='SUCCEDED')">
>       <ret>
>          <xsl:copy-of select="$file2//ret/*" />
>       </ret>
>    </xsl:when>
>    <xsl:otherwise>
>              <xsl:apply-templates select="//ret|$file2//ret">
>                <xsl:sort select="Msg/filingType"  order="ascending"
> data-type= "text"/>
>                <xsl:sort select="Msg/State"  order="ascending"
> data-type="number"/>
>              </xsl:apply-templates>
>
>    </xsl:otherwise>
>  </xsl:choose>
> </xsl:template>
>
> What this says is:
>
> "If the first file contains no State element that is set to "PENDING" or
> "SUCCEEDED", output the contents of all the <ret> elements from the first
> file, and ignore the second file.
>
> Otherwise, if the second file contains no State element that is set to
> "PENDING" or "SUCCEEDED", output the contents of all the <ret> elements from
> the second file, and ignore the first file.
>
> Otherwise process the ret elements from both files, sorted first by
> filingType and then by State."
>
> Now:
>
> (a) is this really what you want to do? It seems very odd logic to me.
>
> (b) none of the messages in your input have a filingType element, so sorting
> by it seems a little pointless.
>
> (c) the messages do have a State element, but it is not numeric, so
> specifying data-type="number" will cause all the sort keys to be evaluated
> as NaN, which means there is effectively no sorting.
>
> Michael Kay
> http://www.saxonica.com/
>
>
>
>> -----Original Message-----
>> From: Mohit Anchlia [mailto:mohitanchlia@xxxxxxxxx]
>> Sent: 10 September 2008 19:30
>> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
>> Subject: Re: [xsl] xslt sort dilemna
>>
>> Thanks for taking interest in my problem. Here are complete details:
>>
>> 1. xml file A:
>> <body>
>> <ns2:getMessages xmlns:ns2="http://www.abc.com/wsdl/v";>
>>          <ret>
>>             <Msg>
>>                <cid>103850015_0_1219420995471</cid>
>>                <fid>41</fid>
>>                <filing>IS</filing>
>>                <State>SUCCEEDED</State>
>>
>> <rxTimestamp>2008-08-25T16:54:55.838-07:00</rxTimestamp>
>>                <details>
>>                   <Error>
>>                      <Problem>Its pending</Problem>
>>                   </Error>
>>                </details>
>>             </Msg>
>>          </ret>
>>          <ret>
>>             <CustMsg>
>>                <cid>103850015_0_1219420995471</cid>
>>                <fid>42</fid>
>>                <filing>IS</filing>
>>                <State>PENDING</State>
>>
>> <rxTimestamp>2008-08-25T16:54:55.839-07:00</rxTimestamp>
>>                <details>
>>                   <Error>
>>                      <Problem>Its pending</Problem>
>>                   </Error>
>>                </details>
>>             </CustMsg>
>>          </ret>
>> </ns2:getMessages>
>> </body>
>>
>> 2. xml file B:
>> <body>
>> <ns2:getMessages xmlns:ns2="http://www.abc.com/wsdl/v";>
>>          <ret>
>>             <Msg>
>>                <cid>103850015_0_1219420995471</cid>
>>                <fid>41</fid>
>>                <filing>IS</filing>
>>                <State>PENDING</State>
>>             </Msg>
>>          </ret>
>> </ns2:getMessages>
>> </body>
>>
>> 3. xsl file:
>> <?xml version="1.0"?>
>> <xsl:stylesheet
>> xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0"
>> exclude-result-prefixes="xmlns:ns2 ns2 xmlns"> <xsl:output
>> method="xml" indent="yes" /> <xsl:variable name="file2"
>> select="document('EFF')" /> <xsl:key name='PENDING'
>> match='statusMsg' use='./State'/> <xsl:template match="/">
>>    <xsl:choose>
>>     <xsl:when test="not(//State='PENDING')
>>                 and not(//State='SUCCEDED')">
>>        <ret>
>>           <xsl:copy-of select="//ret/*" />
>>        </ret>
>>     </xsl:when>
>>     <xsl:when test="not($file2//State='PENDING')
>>                 and not($file2//State='SUCCEDED')">
>>        <ret>
>>           <xsl:copy-of select="$file2//ret/*" />
>>        </ret>
>>     </xsl:when>
>>     <xsl:otherwise>
>>               <xsl:apply-templates select="//ret|$file2//ret">
>>                 <xsl:sort select="Msg/filingType"
>> order="ascending" data-type= "text"/>
>>                 <xsl:sort select="Msg/State"
>> order="ascending" data-type="numb er"/>
>>               </xsl:apply-templates>
>>
>>     </xsl:otherwise>
>>   </xsl:choose>
>> </xsl:template>
>> <xsl:template match="*">
>>  <xsl:element name="{name()}" namespace="{namespace-uri()}">
>>    <xsl:choose>
>>      <xsl:when test=".='PENDING'">
>>              <xsl:text>1</xsl:text>
>>      </xsl:when>
>>      <xsl:when test=".='SUCCEEDED'">
>>              <xsl:text>2</xsl:text>
>>      </xsl:when>
>>    <xsl:otherwise>
>>     <xsl:choose>
>>      <xsl:when test="*">
>>        <xsl:apply-templates/>
>>      </xsl:when>
>>      <xsl:otherwise>
>>         <xsl:value-of select="." />
>>      </xsl:otherwise>
>>     </xsl:choose>
>>    </xsl:otherwise>
>>   </xsl:choose>
>>  </xsl:element>
>> </xsl:template>
>> </xsl:stylesheet>
>>
>> 4. Output:
>> <?xml version="1.0" encoding="UTF-8"?>
>> <ret>
>>             <Msg>
>>                <cid>103850015_0_1219420995471</cid>
>>                <fid>41</fid>
>>                <filing>IS</filing>
>>                <State>2</State>
>>
>> <rxTimestamp>2008-08-25T16:54:55.838-07:00</rxTimestamp>
>>                <details>
>>                   <Error>
>>                      <Problem>Its pending</Problem>
>>                   </Error>
>>                </details>
>>             </Msg>
>>          </ret>
>> <ret>
>>             <CustMsg>
>>                <cid>103850015_0_1219420995471</cid>
>>                <fid>42</fid>
>>                <filing>IS</filing>
>>                <State>1</State>
>>
>> <rxTimestamp>2008-08-25T16:54:55.839-07:00</rxTimestamp>
>>                <details>
>>                   <Error>
>>                      <Problem>Its pending</Problem>
>>                   </Error>
>>                </details>
>>             </CustMsg>
>>          </ret>
>> <ret>
>>             <Msg>
>>                <cid>103850015_0_1219420995471</cid>
>>                <fid>41</fid>
>>                <filing>IS</filing>
>>                <State>1</State>
>>             </Msg>
>>          </ret>
>>
>> 5. Expected Output:
>> <ret>
>>             <CustMsg>
>>                <cid>103850015_0_1219420995471</cid>
>>                <fid>42</fid>
>>                <filing>IS</filing>
>>                <State>1</State>
>>
>> <rxTimestamp>2008-08-25T16:54:55.839-07:00</rxTimestamp>
>>                <details>
>>                   <Error>
>>                      <Problem>Its pending</Problem>
>>                   </Error>
>>                </details>
>>             </CustMsg>
>>          </ret>
>> <ret>
>>             <Msg>
>>                <cid>103850015_0_1219420995471</cid>
>>                <fid>41</fid>
>>                <filing>IS</filing>
>>                <State>1</State>
>>             </Msg>
>>          </ret>
>> <ret>
>>             <Msg>
>>                <cid>103850015_0_1219420995471</cid>
>>                <fid>41</fid>
>>                <filing>IS</filing>
>>                <State>2</State>
>>
>> <rxTimestamp>2008-08-25T16:54:55.838-07:00</rxTimestamp>
>>                <details>
>>                   <Error>
>>                      <Problem>Its pending</Problem>
>>                   </Error>
>>                </details>
>>             </Msg>
>>          </ret>
>> ---
>> With above xsl I expected State with value 2 to come last.
>> But, with your explanation now I understand why it might not
>> be working. Is there any alternative method that I can use to
>> sort in the same XSL file. Please let me know if I omitted something.
>>
>>
>> On Wed, Sep 10, 2008 at 8:55 AM, Wendell Piez
>> <wapiez@xxxxxxxxxxxxxxxx> wrote:
>> > Mohit,
>> >
>> > At 11:17 AM 9/10/2008, you wrote:
>> >>
>> >> Thanks. I was thinking that sort gets applied to output if
>> it's put
>> >> inside xsl:apply-templates, but it looks like it just
>> works on input.
>> >> Thanks for the explanation.
>> >
>> > You're welcome, but I should also warn you that this bit of
>> confusion
>> > may be indicative of a deeper problem, namely a hazy
>> understanding of
>> > the processing model.
>> >
>> > As has been repeated often on this list, XSLT doesn't
>> "change" or even
>> > "operate" on anything. What it does is build XML. Most commonly, it
>> > builds its output XML by following a set of rules (the
>> stylesheet) as
>> > applied to another XML, which is considered the "input".
>> (In your case
>> > it is complicated by the fact that you have more than one
>> input file,
>> > but the basic situation is the same.) The XSLT process
>> doesn't change
>> > the input at
>> > all: when the operation is complete, any input is still
>> there exactly
>> > as it was. If your process has run successfully, you also
>> now have an output.
>> >
>> > A sort, or for that matter any XSLT instruction or specification,
>> > doesn't work on output or on input. It simply says
>> something about how
>> > the output (the "result") is built.
>> >
>> > This matters here because as long as you persist in thinking you're
>> > sorting output or sorting input, as opposed to specifying the rules
>> > whereby your processor builds the result, you're unlikely
>> to be able
>> > to set those rules up properly. XSLT has a "normal" way of
>> operating:
>> > by default, it will build its output in an order
>> corresponding to the
>> > order of the nodes in the input that it selects for examination
>> > ("processing"). What a sort does is override this behavior
>> by telling
>> > the processor to put the results in a different order. So
>> you are "sorting" the input, but what "gets sorted" is the output.
>> >
>> > This makes no sense at all until you understand how any XSLT
>> > transformation works, at which point it becomes obvious, as in "but
>> > how else could it be?", and much easier to manage. The
>> result reflects
>> > an imposed ("sorted") order of the input data instead of
>> its native "document order".
>> >
>> >> Is there a way I could do this in one xslt itself?
>> >
>> > Probably, but you haven't given us enough information to say. You
>> > haven't even given us enough information to determine if
>> your problem
>> > is due to a bug in your XSLT engine, or in something you
>> are doing or not doing.
>> >
>> > I suggest you try again to compose a complete problem. Show us a
>> > minimal small example of input, the code that you are
>> currently using,
>> > the result it is generating, and a description of what you want
>> > instead. Also tell us what XSLT processor you are using in case the
>> > processor isn't doing the right thing (since we can't guess what it
>> > will do if it doesn't do what it's supposed to).
>> >
>> > Cheers,
>> > Wendell
>> >
>> >
>> >
>> ======================================================================
>> > Wendell Piez
>> mailto:wapiez@xxxxxxxxxxxxxxxx
>> > Mulberry Technologies, Inc.
>> http://www.mulberrytech.com
>> > 17 West Jefferson Street                    Direct Phone:
>> 301/315-9635
>> > Suite 207                                          Phone:
>> 301/315-9631
>> > Rockville, MD  20850                                 Fax:
>> 301/315-8285
>> >
>> ----------------------------------------------------------------------
>> >  Mulberry Technologies: A Consultancy Specializing in SGML and XML
>> >
>> ======================================================================

Current Thread