Re: [xsl] xslt sort dilemna

Subject: Re: [xsl] xslt sort dilemna
From: "Mohit Anchlia" <mohitanchlia@xxxxxxxxx>
Date: Wed, 10 Sep 2008 11:29:59 -0700
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