[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: xsl: parsing through specific child nodes

Subject: Re: xsl: parsing through specific child nodes
From: "Mohit Anchlia" <mohitanchlia@xxxxxxxxx>
Date: Tue, 9 Sep 2008 09:01:51 -0700
Re:  xsl: parsing through specific child nodes
Could somebody please help me understand why I am losing indentation.
Below are the complete details.

On Mon, Sep 8, 2008 at 12:57 PM, Mohit Anchlia <mohitanchlia@xxxxxxxxx> wrote:
> So I kind of got it working but need some help, I'll first post xml,
> xsl and output and then ask my questions:
>
> 1. XML
>
> <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>
>               <details>
>                  <Error>
>                     <Problem>Its pending</Problem>
>                  </Error>
>               </details>
>            </Msg>
>         </ret>
> </ns2:getMessages>
> </body>
>
>
> 2. xsl
>
> <?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:for-each select="//ret/*">
>             <xsl:apply-templates select="*"/>
>          </xsl:for-each>
>    </xsl:otherwise>
>  </xsl:choose>
> </xsl:template>
> <xsl:template match="ret">
>       <xsl:apply-templates select="*"/>
> </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:otherwise>
>    <xsl:choose>
>     <xsl:when test="*">
>       <xsl:apply-templates select="*"/>
>     </xsl:when>
>     <xsl:otherwise>
>        <xsl:value-of select="." />
>     </xsl:otherwise>
>    </xsl:choose>
>   </xsl:otherwise>
>  </xsl:choose>
>  </xsl:element>
> </xsl:template>
> </xsl:stylesheet>
>
> 3. output
>
> <?xml version="1.0" encoding="UTF-8"?>
> <cid>103850015_0_1219420995471</cid>
> <fid>41</fid>
> <filing>IS</filing>
> <State>1</State>
> <details>
> <Error>
> <Problem>Its pending</Problem>
> </Error>
> </details>
>
> Questions:
>
> 1. But now I don't get <ret> and <Msg> tags, Msg tag in one xml could
> be Msg and other it could <CMsg> rest of the tags are same. How can I
> get them.
> 2. Also I am losing the indentation, it's all appearing on first
> column. I did get rid of ns2 though.
> 3. In above xsl what do I have to do if I want to make sure that it's
> the element node "State" whose child text node is "PENDING"?
>
> Also am I doing this xsl transformation correctly, in the sense that
> do you see any problems in terms of how it's done, efficiency etc.
>
> Thanks for your help.
> On Mon, Sep 8, 2008 at 12:31 PM, Michael Kay <mike@xxxxxxxxxxxx> wrote:
>> When you apply-templates to the ret element it does apply-templates on the
>> Msg element, which does xsl:copy-of the Msg element. It does not not do an
>> apply-templates on the State element so the code that replaces "PENDING"
>> with "1" is never activated.
>>
>> Michael Kay
>> http://www.saxonica.com/
>>
>>> -----Original Message-----
>>> From: Mohit Anchlia [mailto:mohitanchlia@xxxxxxxxx]
>>> Sent: 08 September 2008 18:45
>>> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
>>> Subject: Re:  xsl: parsing through specific child nodes
>>>
>>> Sorry I gave incorrect xml document:
>>>
>>> Here is the correct one:
>>>
>>> 1. xml document
>>>
>>> <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>
>>> 2. 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='Msg' 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"/>
>>>    </xsl:otherwise>
>>>  </xsl:choose>
>>> </xsl:template>
>>> <xsl:template match="ret">
>>>       <xsl:apply-templates select="*"/>
>>>
>>> </xsl:template>
>>> <xsl:template match="*">
>>>
>>>  <xsl:copy>
>>>   <xsl:choose>
>>>     <xsl:when test="text()='PENDING'">
>>>             <xsl:text>1</xsl:text>
>>>     </xsl:when>
>>>   <xsl:otherwise>
>>>     <xsl:copy-of select="." />
>>>
>>>   </xsl:otherwise>
>>>  </xsl:choose>
>>>  </xsl:copy>
>>>
>>> </xsl:template>
>>> </xsl:stylesheet>
>>>
>>> 3. Output:
>>>
>>> <?xml version="1.0" encoding="UTF-8"?>
>>>
>>> <Msg xmlns:ns2="http://www.abc.com/wsdl/v">
>>> <Msg>
>>>               <cid>103850015_0_1219420995471</cid>
>>>               <fid>41</fid>
>>>               <filing>IS</filing>
>>>               <State>PENDING</State>
>>>            </Msg>
>>> </Msg>
>>>
>>>
>>> On Mon, Sep 8, 2008 at 10:03 AM, Michael Kay
>>> <mike@xxxxxxxxxxxx> wrote:
>>> > In your match="/" template, the only apply-templates is to
>>> an element
>>> > called "ret". There is no element named ret in your source
>>> document.
>>> > Therefore the template rule with match="*" will never fire,
>>> therefore
>>> > the code that replaces "PENDING" by "1" will not be executed.
>>> >
>>> > Michael Kay
>>> > http://www.saxonica.com/
>>> >
>>> >> -----Original Message-----
>>> >> From: Mohit Anchlia [mailto:mohitanchlia@xxxxxxxxx]
>>> >> Sent: 08 September 2008 17:48
>>> >> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
>>> >> Subject: Re:  xsl: parsing through specific child nodes
>>> >>
>>> >> So I tried various things but it doesn't seem to be working.
>>> >> I'll give the complete information:
>>> >>
>>> >> 1. xml file:
>>> >> <?xml version="1.0" encoding="UTF-8"?> <Msg
>>> >> xmlns:ns2="http://www.abc.com/wsdl/v">
>>> >> <Msg>
>>> >>                <cid>103850015_0_1219420995471</cid>
>>> >>                <fid>41</fid>
>>> >>                <filing>IS</filing>
>>> >>                <State>PENDING</State>
>>> >>             </Msg>
>>> >> </Msg>
>>> >>
>>> >> 2. 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='Msg' 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"/>
>>> >>     </xsl:otherwise>
>>> >>   </xsl:choose>
>>> >> </xsl:template>
>>> >> <xsl:template match="ret">
>>> >>        <xsl:apply-templates select="*"/> </xsl:template>
>>> >> <xsl:template match="*">  <xsl:copy>
>>> >>    <xsl:choose>
>>> >>      <xsl:when test="text()='PENDING'">
>>> >>              <xsl:text>1</xsl:text>
>>> >>      </xsl:when>
>>> >>    <xsl:otherwise>
>>> >>      <xsl:copy-of select="." />
>>> >>    </xsl:otherwise>
>>> >>   </xsl:choose>
>>> >>  </xsl:copy>
>>> >> </xsl:template>
>>> >> </xsl:stylesheet>
>>> >>
>>> >> 3. Output:
>>> >> <?xml version="1.0" encoding="UTF-8"?> <Msg
>>> >> xmlns:ns2="http://www.abc.com/wsdl/v">
>>> >> <Msg>
>>> >>                <cid>103850015_0_1219420995471</cid>
>>> >>                <fid>41</fid>
>>> >>                <filing>IS</filing>
>>> >>                <State>PENDING</State>
>>> >>             </Msg>
>>> >> </Msg>
>>> >>
>>> >> 4.expected output:
>>> >>
>>> >> <?xml version="1.0" encoding="UTF-8"?> <Msg>
>>> >>                <cid>103850015_0_1219420995471</cid>
>>> >>                <fid>41</fid>
>>> >>                <filing>IS</filing>
>>> >>                <State>1</State>
>>> >>             </Msg>
>>> >> </Msg>
>>> >>
>>> >>
>>> >> First I don't understand how there are 2 Msg nodes. And
>>> >> second I wasn't able to get rid of namespace node by using
>>> >> <element> as suggested by Michael, it's still copying the
>>> >> namespace node.
>>> >> On Mon, Sep 8, 2008 at 6:52 AM, Mukul Gandhi
>>> >> <gandhi.mukul@xxxxxxxxx> wrote:
>>> >> > On Mon, Sep 8, 2008 at 1:16 AM, Mohit Anchlia
>>> >> <mohitanchlia@xxxxxxxxx> wrote:
>>> >> >> 1. So would above template mentioned by Mukul also output
>>> >> node HIJ ?
>>> >> >
>>> >> > I think, "outputting the node" is not the correct
>>> >> terminology. We can
>>> >> > copy the node to the result tree, or write something else to the
>>> >> > result tree, derived from the properties of the input nodes.
>>> >> >
>>> >> >>       <xsl:when test="local-name()="HIJ" and . = 'YYYYYY'">
>>> >> >
>>> >> > This statement will probably not compile, as I can see some
>>> >> misplaced quotes.
>>> >> >
>>> >> >
>>> >> >> 3. Currently I am using XSLT 1.0 and I am using JAXP which
>>> >> uses Xalan.
>>> >> >> How do I start using XSLT 2.0.
>>> >> >
>>> >> > You need to download an XSLT 2.0 processor, like Saxon and
>>> >> using it as
>>> >> > described in the documentation.
>>> >> >
>>> >> >> Would it just be matter of upping version in stylesheet node?
>>> >> >
>>> >> > No. version="2.0" is just a hint to the processor. You need
>>> >> to supply
>>> >> > the XSLT 2.0 stylesheet to a XSLT 2.0 processor like Saxon.
>>> >> >
>>> >> >
>>> >> > --
>>> >> > Regards,
>>> >> > Mukul Gandhi

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.