[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] xsl: parsing through specific child nodes


Subject: Re: [xsl] xsl: parsing through specific child nodes
From: "Mohit Anchlia" <mohitanchlia@xxxxxxxxx>
Date: Tue, 9 Sep 2008 09:42:29 -0700

It's apache xalan. strange part is that if I remove select=* from
apply-templates then it indents properly.

On Tue, Sep 9, 2008 at 9:21 AM, Michael Kay <mike@xxxxxxxxxxxx> wrote:
>> Could somebody please help me understand why I am losing indentation.
>
> What processor are you using? The result of indent="yes" is not specified
> precisely in the spec, and I seem to recall some processors just give you a
> newline and no spaces. Not very friendly, but legal.
>
> Michael Kay
> http://www.saxonica.com/
>
>> 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] 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] 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
Keywords