ms wrote:
Hi:
 Thank you for all your help. 
Tell me, did it help? What did you try and what worked, and what did not 
work?
Here is the sample XML:
Thanks
My sample XSLfo:
This appeared being XSLT, not xsl-fo. However, it does produce xsl-fo. 
I'd have liked a less verbose version, with all the not-necessary things 
removed. Doing so, will likely increase your chances to responses. I did 
the cleanup myself. See my comments about the content (I tried to make 
the xml/xslt readable in the mail).
   <fo:block>
      <xsl:apply-templates select="test"/>
   </fo:block>
	
<xsl:template match="test">
   <fo:block>
       <xsl:apply-templates/>
   </fo:block>
</xsl:template>
This pair adds nothing to your logic (and a nested block doesn't 
either). A single <xsl:apply-templates /> would've sufficed.
   <xsl:template match="level1">
      <xsl:choose>
         <xsl:when test=".//locn">
            <xsl:if test=".//locn/cond1=$val1 and
                          .//locn/cond2=$val2">
This looks to me as a very dangerous construct (and potentially very 
resource intensive). What you say in the test-clause is "search the 
whole tree from here and look for a "locn" node. Search again all the 
"locn" nodes from the current child and from all you find, check its 
"cond1 and cond2" node and compare its value with the value in $val1 and 
$val2, if there's a match, it is true. In short: whatever the depth of 
"cond1" and "cond2" nodes, if any matches $val1 and $val2, it is true. I 
can hardly imagine that this is your intend (on XSLT 2 this comparison 
works differently and will likely always fail).
I am not sure of what you want to accomplish here. At least you can 
remove the double test, which adds nothing:
<xsl:when test=".//locn/cond1=$val1 and
               .//locn/cond2=$val2">
And if the logic you want is: "if any of the conditions of the current 
level1 matches $val1 and $val2, output the complete tree from here. If 
not, do not output the tree, you should write it as follows:
<xsl:when test="locn/cond1=$val1 and
               locn/cond2=$val2">
which tests if any cond1 node equals $val1 and if any cond2 node equals 
$val2. If you only want to match the first such nodes, it becomes as 
follows:
<xsl:when test="locn[1]/cond1[1]=$val1 and
               locn[1]/cond2[1]=$val2">
And be aware of evil whitespace:
<xsl:when test="normalize-space(locn[1]/cond1[1])
               = normalize-space($val1) ....
	
<xsl:otherwise>
   <xsl:call-template name="level">
       <xsl:with-param name="format">1</xsl:with-param>
   </xsl:call-template>
</xsl:otherwise>
This "xsl:otherwise" is never called. However, I assume in your original 
code this has a purpose? You mean to apply a different numbering when 
there is no locn node whatsoever somewhere down the tree?
<xsl:template match="level2">
You are really going to repeat the same logic again? Why didn't you try 
to apply my approach here with the substring matches? This makes your 
code extremely unreadable and unmaintainable.
<xsl:choose>
   <xsl:when test=".//locn">
   <xsl:if test=".//locn/cond1=$val1 and
                 .//locn/cond2=$val2">
Here you apply exactly the same tests as above. It is recommended, in 
any language, to repeat as little as possible. This logic should all go 
into the same template match (this way you'll have to copy it for every 
level!).
<xsl:number format="A"/>
This appears to me as the only difference per level. I recommend using a 
lookup table or something for this kind of thing.
<xsl:otherwise>
   <xsl:call-template name="level">
       <xsl:with-param name="format">a</xsl:with-param>
   </xsl:call-template>
</xsl:otherwise>
This, again, is never called.
<xsl:template name="level">
This named template is never called.
<xsl:choose>
   <xsl:when test="$format = '1'">
      <xsl:number format="1"/>.</fo:inline>
This kind of structure is a waste of space and makes it hard for you to 
maintain the whole thing. Remove the xsl:choose and write it like this, 
as a single statement:
<xsl:number format="{$format}"/>
Which does precisely what you want: output in the format you supply. 
Now val1 and val 2 are high and deep. So the expected
output is: 
2 This level should be displayed only if the
conditions are high and deep.
Which will never happen, see my comments above.
However, instead of 2, it should be numbered 1 since
it is the first level.
Again (and still) I am stuck. You want all numbers on one level numbered 
the same? Than you do not need a numbering scheme. Your input data is 
way to vague to make it understandable: all texts are equal and you do 
not make any effort in clearly distinguishing what should go where. In 
your posts, levels are not indented and the subject is too complex to 
understand from three lines.
In addition, you fail to answer my primary question: how and with what 
indentation should a certain input be displayed and what condition must 
be met to restart numbering (if it is indeed about numbering, it looks 
now as if every number should start with 1?). I'd like to help, but you 
really should make your subject clear.
Desired output on the PDF would be:
1. This level should be displayed only if the
conditions are high and deep.
  
From this I reckon you only want one level to be output? Consider the 
suggested changes for your main xsl:choose.
I asked you this before, and now I will do so again: take the message of 
a poster, and go through it and add your comments so that you don't 
leave unanswered any question he/she asks.
In addition: please try to apply the former replies to your query. They 
seem (as far as I can tell) to contain the resolution. To help you apply 
that logic, here's a quick and dirty hack that aims to output what you 
want: starting numbering based on the condition. Also, it applies some 
of the tips I gave above. Please look it through carefully and try to 
apply it. It is likely not all you want, but for that, you really have 
to be clearer and try to apply the solutions first. I used the 
translate() function to make the levels a bit easier, however, if you 
prefer, you can make the variable a chain of xsl:if statements. Remove 
the conditionality on the count-attribute and the select-attribute to 
see the whole tree build based on the levels of the input. It outputs, 
using your XML, the following having more L1 items in the main node, 
will increment the number):
1. This level should be displayed only if the
conditions are high and deep.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:fo="http://www.w3.org/1999/XSL/Format">
  
   <xsl:output indent="yes"/>
  
   <xsl:variable name="val1">high</xsl:variable>
   <xsl:variable name="val2">deep</xsl:variable>
  
  
   <xsl:template match="root/test">
       <fo:root
           xmlns:fo="http://www.w3.org/1999/XSL/Format">
           <fo:layout-master-set>
               <fo:simple-page-master master-name="cover">
                   <fo:region-body
                       region-name="coverPage-region-body"
                       margin="18mm" />
               </fo:simple-page-master>
           </fo:layout-master-set>
           <fo:page-sequence master-reference="cover">
               <fo:flow flow-name="coverPage-region-body">
                   <fo:block>
                      
                       <!-- content -->
                       <xsl:apply-templates select="
                           *[starts-with(name(.), 'level')]
                           [locn/cond1=$val1 and locn/cond2=$val2]"/>
                   </fo:block>
               </fo:flow>
           </fo:page-sequence>
       </fo:root>
   </xsl:template>
  
   <xsl:template match="
       *[starts-with(name(.), 'level')]">
      
       <xsl:variable name="level" select="substring(name(.), 6,1)" />
       <xsl:variable name="format" select="
           concat(translate(substring(name(.), 6,1), '1234567', 
'1aAIi11'),
           translate(substring(name(.), 6,1), '1234567', ' ).).).'))" />
          
       <fo:list-block space-before="6pt"
           space-before.conditionality="retain">
           <fo:list-item>
               <fo:list-item-label end-indent="label-end()">
                   <fo:block>
                       <xsl:number
                           format="{$format}"
                           level="single"
                           count="
                               *[substring(name(.), 6, 1) = $level]
                               [locn/cond1=$val1 and locn/cond2=$val2]"/>
                          
                   </fo:block>
               </fo:list-item-label>
               <fo:list-item-body start-indent="body-start()"
                   end-indent="0pt">
                   <fo:block>
                       <xsl:apply-templates />
                   </fo:block>
               </fo:list-item-body>
           </fo:list-item>
       </fo:list-block>
   </xsl:template>
  
</xsl:stylesheet>
Cheers,
-- Abel Braaksma
  http://www.nuntia.nl