Groups > Design > Microsoft xsl > Re: Question on flow




Question on flow

Question on flow
Tue, 1 Apr 2008 12:59:03 -0700
I have been working on my XSLT page and have a couple questions on flow.

In my example XSLT file, I have have 4 Templates.  Based on how mine works I 
think I understand how the flow works but am not sure.

It seems that only the 1st template is the driving template, similar to 
Main() in C or the startup function in any program.  If I don't call any 
other function, from a startup function then only the startup function gets 
executed even if there there are other functions in my program (discounting 
events, of course).

In XSLT, it seems that the 1st template is like your startup routine.  If 
you don't do an <xsl:apply-templates> or <xsl:call-template> only
this 1st 
template will get run and it will execute all the commands in it until it 
hits the </xsl:template> tag.

All the other templates get executed only if they are applied or called.

This seems to be what happens.  If I take all the apply-templates out of my 
1st template, none of the other templates get executed and all the 1st 
template does.

I am a little confused on the necessity of using the <xsl:copy> (except to

soft code the root element), as in my example.  As it works exactly the same 
if I change it to <REPORTING>.  In the copy case, it will put whatever my

root element is as my new root element and the other case will put 
<REPORTING> as my root element.  Other than that, there doesn't seem to be

any difference.

I also am a little confused as to the use of "/*" vs "/" vs
"REPORT" in my 
first template line.

Both "/*" and "REPORT" give me the same results.  But if I
have "/" and 
<xsl:copy>, I don't get a root tag.  If I do "/" and
"<REPORTING> (in place 
of the <xsl:copy>), it works fine with <REPORTING> as my root tag.

************************************************
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

 <xsl:output method="xml" indent="yes"/>

 <xsl:template match="REPORT">
  <xsl:copy>
   <xsl:apply-templates
  select="FORMS/FORM/FIELDS/*[not(starts-with(name(), 'SCMCOMMENTS')) and
not(starts-with(name(), 'GEN_COMMENTS')) and not(starts-with(name(),
'CMPHIST_TXT'))]"/>
   <form>
    <sectionNumber>0</sectionNumber>
    <primary>True</primary>
    <formName>
     <xsl:value-of select="FORMS/FORM/@FORMCODE"/>
    </formName>
    <tagName>SCMCOMMENTS_1</tagName>
    <flags>0</flags>
    <format>0</format>
    <value>
     <xsl:apply-templates
select="FORMS/FORM/FIELDS/*[starts-with(name(),
'SCMCOMMENTS')]"/>
    </value>
   </form>
   <form>
    <sectionNumber>0</sectionNumber>
    <primary>True</primary>
    <formName>
     <xsl:value-of select="FORMS/FORM/@FORMCODE"/>
    </formName>
    <tagName>GEN_COMMENTS_1</tagName>
    <flags>0</flags>
    <format>0</format>
    <value>
     <xsl:apply-templates
select="FORMS/FORM/FIELDS/*[starts-with(name(),
'GEN_COMMENTS')]"/>
    </value>
   </form>
   <form>
    <sectionNumber>0</sectionNumber>
    <primary>True</primary>
    <formName>
     <xsl:value-of select="FORMS/FORM/@FORMCODE"/>
    </formName>
    <tagName>CMPHIST_TXT</tagName>
    <flags>0</flags>
    <format>0</format>
    <value>
     <xsl:apply-templates
select="FORMS/FORM/FIELDS/*[starts-with(name(),
'CMPHIST_TXT')]"/>
    </value>
   </form>
   <form>
    <sectionNumber>
     <xsl:value-of select="FORMS/FORM/@SECCODE"/>
    </sectionNumber>
    <primary>True</primary>
    <formName>
     <xsl:value-of select="FORMS/FORM/@FORMCODE"/>
    </formName>
    <tagName>FormFormats</tagName>
    <flags>0</flags>
    <format>0</format>
    <value>
     <xsl:apply-templates select="FORMS/FORM/@*"/>
    </value>
   </form>
   <xsl:apply-templates
select="FORMS/FORM/attachments/attachment"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="FIELDS/*[not(starts-with(name(), 'SCMCOMMENTS'))
and
not(starts-with(name(), 'GEN_COMMENTS')) and not(starts-with(name(),
'CMPHIST_TXT'))]">
  <form>
   <sectionNumber>
    <xsl:text>0</xsl:text>
   </sectionNumber>
   <primary>True</primary>
   <formName>
    <xsl:value-of select="../../@FORMCODE"/>
   </formName>
   <tagName>
    <xsl:value-of select="name()"/>
   </tagName>
   <flags>0</flags>
   <format>0</format>
   <value>
    <xsl:value-of select="."/>
   </value>
  </form>
 </xsl:template>

 <xsl:template match="FIELDS/*[starts-with(name(),
'SCMCOMMENTS')]">
  <xsl:value-of select="."/>
  <xsl:if test="position() != last()">
   <xsl:text> </xsl:text>
  </xsl:if>
 </xsl:template>
 <xsl:template match="FIELDS/*[starts-with(name(),
'GEN_COMMENTS')]">
  <xsl:value-of select="."/>
  <xsl:if test="position() != last()">
   <xsl:text> </xsl:text>
  </xsl:if>
 </xsl:template>
 <xsl:template match="FIELDS/*[starts-with(name(),
'CMPHIST_TXT')]">
  <xsl:value-of select="."/>
  <xsl:if test="position() != last()">
   <xsl:text> </xsl:text>
  </xsl:if>
 </xsl:template>

 <xsl:template match="FORM/@*">
  <xsl:value-of select="concat(name(), '=', .)"/>
  <xsl:if test="position() != last()">
   <xsl:text> </xsl:text>
  </xsl:if>
 </xsl:template>

</xsl:stylesheet>
************************************************

Am I close?

Thanks,

Tom 

Post Reply
Re: Question on flow
Wed, 2 Apr 2008 04:03:19 -0700
On Apr 2, 12:59 am, "tshad" <ts...@dslextreme.com> wrote:
> I have been working on my XSLT page and have a couple questions on flow.
>
> In my example XSLT file, I have have 4 Templates.  Based on how mine works
I
> think I understand how the flow works but am not sure.
>
> It seems that only the 1st template is the driving template, similar to
> Main() in C or the startup function in any program.  If I don't call any
> other function, from a startup function then only the startup function
gets
> executed even if there there are other functions in my program
(discounting
> events, of course).
>
> In XSLT, it seems that the 1st template is like your startup routine.  If
> you don't do an <xsl:apply-templates> or <xsl:call-template>
only this 1st
> template will get run and it will execute all the commands in it until it
> hits the </xsl:template> tag.
>
> All the other templates get executed only if they are applied or called.
>
> This seems to be what happens.  If I take all the apply-templates out of
my
> 1st template, none of the other templates get executed and all the 1st
> template does.
>
> I am a little confused on the necessity of using the <xsl:copy>
(except to
> soft code the root element), as in my example.  As it works exactly the
same
> if I change it to <REPORTING>.  In the copy case, it will put
whatever my
> root element is as my new root element and the other case will put
> <REPORTING> as my root element.  Other than that, there doesn't seem
to be
> any difference.
>
> I also am a little confused as to the use of "/*" vs
"/" vs "REPORT" in my
> first template line.
>
> Both "/*" and "REPORT" give me the same results.  But
if I have "/" and
> <xsl:copy>, I don't get a root tag.  If I do "/" and
"<REPORTING> (in place
> of the <xsl:copy>), it works fine with <REPORTING> as my root
tag.
>
> ************************************************
> <xsl:stylesheet
>     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>     version="1.0">
>
>  <xsl:output method="xml" indent="yes"/>
>
>  <xsl:template match="REPORT">
>   <xsl:copy>
>    <xsl:apply-templates
>   select="FORMS/FORM/FIELDS/*[not(starts-with(name(), 'SCMCOMMENTS'))
and
> not(starts-with(name(), 'GEN_COMMENTS')) and not(starts-with(name(),
> 'CMPHIST_TXT'))]"/>
>    <form>
>     <sectionNumber>0</sectionNumber>
>     <primary>True</primary>
>     <formName>
>      <xsl:value-of select="FORMS/FORM/@FORMCODE"/>
>     </formName>
>     <tagName>SCMCOMMENTS_1</tagName>
>     <flags>0</flags>
>     <format>0</format>
>     <value>
>      <xsl:apply-templates
select="FORMS/FORM/FIELDS/*[starts-with(name(),
> 'SCMCOMMENTS')]"/>
>     </value>
>    </form>
>    <form>
>     <sectionNumber>0</sectionNumber>
>     <primary>True</primary>
>     <formName>
>      <xsl:value-of select="FORMS/FORM/@FORMCODE"/>
>     </formName>
>     <tagName>GEN_COMMENTS_1</tagName>
>     <flags>0</flags>
>     <format>0</format>
>     <value>
>      <xsl:apply-templates
select="FORMS/FORM/FIELDS/*[starts-with(name(),
> 'GEN_COMMENTS')]"/>
>     </value>
>    </form>
>    <form>
>     <sectionNumber>0</sectionNumber>
>     <primary>True</primary>
>     <formName>
>      <xsl:value-of select="FORMS/FORM/@FORMCODE"/>
>     </formName>
>     <tagName>CMPHIST_TXT</tagName>
>     <flags>0</flags>
>     <format>0</format>
>     <value>
>      <xsl:apply-templates
select="FORMS/FORM/FIELDS/*[starts-with(name(),
> 'CMPHIST_TXT')]"/>
>     </value>
>    </form>
>    <form>
>     <sectionNumber>
>      <xsl:value-of select="FORMS/FORM/@SECCODE"/>
>     </sectionNumber>
>     <primary>True</primary>
>     <formName>
>      <xsl:value-of select="FORMS/FORM/@FORMCODE"/>
>     </formName>
>     <tagName>FormFormats</tagName>
>     <flags>0</flags>
>     <format>0</format>
>     <value>
>      <xsl:apply-templates select="FORMS/FORM/@*"/>
>     </value>
>    </form>
>    <xsl:apply-templates
select="FORMS/FORM/attachments/attachment"/>
>   </xsl:copy>
>  </xsl:template>
>
>  <xsl:template match="FIELDS/*[not(starts-with(name(),
'SCMCOMMENTS')) and
> not(starts-with(name(), 'GEN_COMMENTS')) and not(starts-with(name(),
> 'CMPHIST_TXT'))]">
>   <form>
>    <sectionNumber>
>     <xsl:text>0</xsl:text>
>    </sectionNumber>
>    <primary>True</primary>
>    <formName>
>     <xsl:value-of select="../../@FORMCODE"/>
>    </formName>
>    <tagName>
>     <xsl:value-of select="name()"/>
>    </tagName>
>    <flags>0</flags>
>    <format>0</format>
>    <value>
>     <xsl:value-of select="."/>
>    </value>
>   </form>
>  </xsl:template>
>
>  <xsl:template match="FIELDS/*[starts-with(name(),
'SCMCOMMENTS')]">
>   <xsl:value-of select="."/>
>   <xsl:if test="position() != last()">
>    <xsl:text> </xsl:text>
>   </xsl:if>
>  </xsl:template>
>  <xsl:template match="FIELDS/*[starts-with(name(),
'GEN_COMMENTS')]">
>   <xsl:value-of select="."/>
>   <xsl:if test="position() != last()">
>    <xsl:text> </xsl:text>
>   </xsl:if>
>  </xsl:template>
>  <xsl:template match="FIELDS/*[starts-with(name(),
'CMPHIST_TXT')]">
>   <xsl:value-of select="."/>
>   <xsl:if test="position() != last()">
>    <xsl:text> </xsl:text>
>   </xsl:if>
>  </xsl:template>
>
>  <xsl:template match="FORM/@*">
>   <xsl:value-of select="concat(name(), '=', .)"/>
>   <xsl:if test="position() != last()">
>    <xsl:text> </xsl:text>
>   </xsl:if>
>  </xsl:template>
>
> </xsl:stylesheet>
> ************************************************
>
> Am I close?
>
> Thanks,
>
> Tom

Hi,

 Lot of peopls they misunderstood here. '/' mention doucment element
not root element.

 your using

<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>

 it shows document element inside content to be pushed to other
templates.

 And put your XML input file.

Regards,
Post Reply
Re: Question on flow
Wed, 2 Apr 2008 08:32:09 -0700
Martin Honnen wrote:
> tshad wrote:
>
>> It seems that only the 1st template is the driving template, similar
>> to Main() in C or the startup function in any program.  If I don't
>> call any other function, from a startup function then only the
>> startup function gets executed even if there there are other
>> functions in my program (discounting events, of course).
>>
>> In XSLT, it seems that the 1st template is like your startup routine.
>
> No, processing does not start at the first template. Processing starts
> at the root node (document node) of your primary XML input document,
> see <URL:http://www.w3.org/TR/xslt#section-Processing-Model>. Then
> the best matching template is used and its content determines which
> nodes are processed next. And there is a built-in template
> (<URL:http://www.w3.org/TR/xslt#built-in-rule>)
>   <xsl:template match="*|/">
>     <xsl:apply-templates/>
>   </xsl:template>
> which makes sure the child nodes of the root node are processed.
> So in your sample XML input the above built-in template is the first
> template to be applied, then the child nodes of the root node
> (document node) are processed which is the 'REPORT' element. As you
> have a matching template for 'REPORT' elements that template is
> applied. And the xsl:apply-templates in that template determine which
> nodes are processed next, and pattern matching determines which
> templates are applied to these nodes.

That makes sense.

But then what is happening as to the use of "/*" vs "/" vs
"REPORT" in my
first template line.

Both "/*" and "REPORT" give me the same results.  But if I
have "/" and
<xsl:copy>, I don't get a root tag.  If I do "/" and
"<REPORTING> (in place
of the <xsl:copy>), it works fine with <REPORTING> as my root tag.

It seems the "/" drops the root node (with copy) and "/*"
(with copy) uses 
the existing root node.

I assume the reason "/" and <REPORT> work is because
"/" is dropping the 
root (document) node but I am supplying my own.

<xsl:template match="/">
  <xsl:copy>

doesn't work (missing root node)

<xsl:template match="/">
  <REPORT>

works - I assume because I am supplying the root node.

<xsl:template match="/*">
  <xsl:copy>

don't know why that doesn't work.

Thanks,

Tom
 

Post Reply
Re: Question on flow
Wed, 2 Apr 2008 08:44:53 -0700
Martin Honnen wrote:
> tshad wrote:
>
>> It seems that only the 1st template is the driving template, similar
>> to Main() in C or the startup function in any program.  If I don't
>> call any other function, from a startup function then only the
>> startup function gets executed even if there there are other
>> functions in my program (discounting events, of course).
>>
>> In XSLT, it seems that the 1st template is like your startup routine.
>
> No, processing does not start at the first template. Processing starts
> at the root node (document node) of your primary XML input document,
> see <URL:http://www.w3.org/TR/xslt#section-Processing-Model>. Then
> the best matching template is used and its content determines which
> nodes are processed next. And there is a built-in template
> (<URL:http://www.w3.org/TR/xslt#built-in-rule>)
>   <xsl:template match="*|/">
>     <xsl:apply-templates/>
>   </xsl:template>
> which makes sure the child nodes of the root node are processed.
> So in your sample XML input the above built-in template is the first
> template to be applied, then the child nodes of the root node
> (document node) are processed which is the 'REPORT' element. As you
> have a matching template for 'REPORT' elements that template is
> applied. And the xsl:apply-templates in that template determine which
> nodes are processed next, and pattern matching determines which
> templates are applied to these nodes.

If it decides which one to choose, why if you have the pattern:

<xsl:template match="FIELDS/*[starts-with(name(),
'SCMCOMMENTS')]">

does it know to use this one:

     <xsl:apply-templates
select="FORMS/FORM/FIELDS/*[starts-with(name(),
'SCMCOMMENTS')]"/>

They aren't the same - but they are similar.  Why did you leave FORMS/FORM/ 
off of the template but not the apply-template?

In my template, I now have:

            <xsl:apply-templates
        select="FORMS/FORM/FIELDS/*[not(starts-with(name(), 'SCMCOMMENTS'))

and
                not(starts-with(name(), 'GEN_COMMENTS')) and
                not(starts-with(name(), 'CMTCONDITION')) and
                not(starts-with(name(), 'CSTCOMMENTS')) and
                not(starts-with(name(), 'SITE_OPINION')) and
                not(starts-with(name(), 'CMPHIST_TXT')) and
                not(starts-with(name(), 'GSU') and ../../@FORMCODE = '(AC)') 
and
                not(name() = 'OTHERFILENUMBER' and ../../@FORMCODE = '(AC)') 
and
                not(name() = 'FNMA_FILENUMBER' and ../../@FORMCODE = 
'(AC)')]"/>

and the template is:

    <xsl:template match="FIELDS/*[not(starts-with(name(),
'SCMCOMMENTS')) 
and
                not(starts-with(name(), 'GEN_COMMENTS')) and
                not(starts-with(name(), 'CMTCONDITION')) and
                not(starts-with(name(), 'CSTCOMMENTS')) and
                not(starts-with(name(), 'SITE_OPINION')) and
                not(starts-with(name(), 'CMPHIST_TXT')) and
                not(starts-with(name(), 'GSU') and ../../@FORMCODE = '(AC)') 
and
                not(name() = 'OTHERFILENUMBER' and ../../@FORMCODE = '(AC)') 
and
                not(name() = 'FNMA_FILENUMBER' and ../../@FORMCODE = 
'(AC)')]">

does it have to match exactly (except for the FORMS/FORM/)?

Thanks,

Tom 

Post Reply
Re: Question on flow
Wed, 02 Apr 2008 13:47:57 +020
tshad wrote:

> It seems that only the 1st template is the driving template, similar to 
> Main() in C or the startup function in any program.  If I don't call any 
> other function, from a startup function then only the startup function gets

> executed even if there there are other functions in my program (discounting

> events, of course).
> 
> In XSLT, it seems that the 1st template is like your startup routine.  

No, processing does not start at the first template. Processing starts 
at the root node (document node) of your primary XML input document, see 
<URL:http://www.w3.org/TR/xslt#section-Processing-Model>. Then the best 
matching template is used and its content determines which nodes are 
processed next. And there is a built-in template 
(<URL:http://www.w3.org/TR/xslt#built-in-rule>)
   <xsl:template match="*|/">
     <xsl:apply-templates/>
   </xsl:template>
which makes sure the child nodes of the root node are processed.
So in your sample XML input the above built-in template is the first 
template to be applied, then the child nodes of the root node (document 
node) are processed which is the 'REPORT' element. As you have a 
matching template for 'REPORT' elements that template is applied. And 
the xsl:apply-templates in that template determine which nodes are 
processed next, and pattern matching determines which templates are 
applied to these nodes.

-- 

	Martin Honnen --- MVP XML
Post Reply
<< Previous 1 2 Next >>
( Page 1 of 2 )
about | contact