xsl-list
[Top] [All Lists]

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

2008-09-09 12:43:03
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(_at_)saxonica(_dot_)com> 
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(_at_)gmail(_dot_)com> 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(_at_)saxonica(_dot_)com> 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(_at_)gmail(_dot_)com]
Sent: 08 September 2008 18:45
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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(_at_)saxonica(_dot_)com>
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(_at_)gmail(_dot_)com]
Sent: 08 September 2008 17:48
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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(_dot_)mukul(_at_)gmail(_dot_)com> wrote:
On Mon, Sep 8, 2008 at 1:16 AM, Mohit Anchlia
<mohitanchlia(_at_)gmail(_dot_)com> 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




--~-----------------------------------------------------------------
-
XSL-List info and archive:
http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to:
http://lists.mulberrytech.com/xsl-list/
or e-mail:
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--





--~-----------------------------------------------------------------
-
XSL-List info and archive:
http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--





--~-----------------------------------------------------------------
-
XSL-List info and archive:
http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--




--~-----------------------------------------------------------------
- XSL-List info and archive:
http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--




--~------------------------------------------------------------------
XSL-List info and archive:
http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--




--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--