xsl-list
[Top] [All Lists]

RE: [xsl] Simple Question

2007-02-01 05:52:16
Well, you ask and you shall receive. :)

Here is my situation: I have an XQueryX document that looks like this
(it's going to be a bit long)

<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="http://www.w3.org/2005/XQueryX";
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
        <mainModule>
                <prolog>
                        <namespaceDecl>
                                <prefix>domain</prefix>
        
<uri>urn:project-object-model:domain</uri>
                        </namespaceDecl>
                        <namespaceDecl>
                                <prefix>base</prefix>
                                <uri>urn:project-object-model:base</uri>
                        </namespaceDecl>
                        <namespaceDecl>
                                <prefix>source</prefix>
        
<uri>urn:project-object-model:source:source</uri>
                        </namespaceDecl>
                </prolog>
                <queryBody>
                        <flworExpr>
                                <forClause>
                                        <forClauseItem>
                                                <typedVariableBinding>
        
<varName>root</varName>
                                                </typedVariableBinding>
                                                <forExpr>
                                                        <pathExpr>
        
<stepExpr>
        
<filterExpr>
        
<functionCallExpr>
        
<functionName>doc</functionName>
        
<arguments>
        
<stringConstantExpr>
        
<value xsi:type="xqu:QName"
xmlns:xqu="http://www.w3.org/2005/XQueryX";>project_source.sourceDocument
</value>
        
</stringConstantExpr>
        
</arguments>
        
</functionCallExpr>
        
</filterExpr>
        
</stepExpr>
        
<stepExpr>
        
<xpathAxis>child</xpathAxis>
        
<nameTest xqu:prefix="source"
xmlns:xqu="http://www.w3.org/2005/XQueryX";>source</nameTest>
        
</stepExpr>
        
<stepExpr>
        
<xpathAxis>child</xpathAxis>
        
<nameTest xqu:prefix="source"
xmlns:xqu="http://www.w3.org/2005/XQueryX";>stream</nameTest>
        
</stepExpr>
                                                        </pathExpr>
                                                </forExpr>
                                        </forClauseItem>
                                </forClause>
                                <whereClause>
                                        <andOp>
                                                <firstOperand>
                                                        <equalOp>
        
<firstOperand>
        
<pathExpr>
        
<stepExpr>
        
<filterExpr>
        
<varRef>
        
<name>root</name>
        
</varRef>
        
</filterExpr>
        
</stepExpr>
        
<stepExpr>
        
<xpathAxis>child</xpathAxis>
        
<nameTest xqu:prefix="domain"
xmlns:xqu="http://www.w3.org/2005/XQueryX";>number</nameTest>
        
</stepExpr>
        
</pathExpr>
        
</firstOperand>
        
<secondOperand>
        
<doubleConstantExpr>
        
<value>2547.3</value>
        
</doubleConstantExpr>
        
</secondOperand>
                                                        </equalOp>
                                                </firstOperand>
                                                <secondOperand>
                                                        <andOp>
        
<firstOperand>
        
<greaterThanOrEqualOp>
        
<firstOperand>
        
<pathExpr>
        
<stepExpr>
        
<filterExpr>
        
<varRef>
        
<name>root</name>
        
</varRef>
        
</filterExpr>
        
</stepExpr>
        
<stepExpr>
        
<xpathAxis>child</xpathAxis>
        
<nameTest xqu:prefix="domain"
xmlns:xqu="http://www.w3.org/2005/XQueryX";>number</nameTest>
        
</stepExpr>
        
</pathExpr>
        
</firstOperand>
        
<secondOperand>
        
<doubleConstantExpr>
        
<value>23940.0</value>
        
</doubleConstantExpr>
        
</secondOperand>
        
</greaterThanOrEqualOp>
        
</firstOperand>
        
<secondOperand>
        
<lessThanOrEqualOp>
        
<firstOperand>
        
<pathExpr>
        
<stepExpr>
        
<filterExpr>
        
<varRef>
        
<name>root</name>
        
</varRef>
        
</filterExpr>
        
</stepExpr>
        
<stepExpr>
        
<xpathAxis>child</xpathAxis>
        
<nameTest xqu:prefix="domain"
xmlns:xqu="http://www.w3.org/2005/XQueryX";>number</nameTest>
        
</stepExpr>
        
</pathExpr>
        
</firstOperand>
        
<secondOperand>
        
<doubleConstantExpr>
        
<value>23950.0</value>
        
</doubleConstantExpr>
        
</secondOperand>
        
</lessThanOrEqualOp>
        
</secondOperand>
                                                        </andOp>
                                                </secondOperand>
                                        </andOp>
                                </whereClause>
                                <returnClause>
                                        <pathExpr>
                                                <stepExpr>
                                                        <filterExpr>
                                                                <varRef>
        
<name>root</name>
        
</varRef>
                                                        </filterExpr>
                                                </stepExpr>
                                                <stepExpr>
        
<xpathAxis>child</xpathAxis>
                                                        <nameTest
xqu:prefix="source"
xmlns:xqu="http://www.w3.org/2005/XQueryX";>stream</nameTest>
                                                </stepExpr>
                                        </pathExpr>
                                </returnClause>
                        </flworExpr>
                </queryBody>
        </mainModule>
</module>

And if I see a number element, I need to take the corresponding
operation (equalOp and andOp) and create N elements (number1 to numberN)
of that operation. Now, xqueryx does not have a composite element that
can easily hold all this, it only works with binary trees. For example,
if I wanted a query that represented this: ((number1 = 10) AND
(number2=10) AND (number3=10) AND (number4=10))

I have to create a binary tree like this:
< orOp >
  <firstOperand>
    < orOp >
      <firstOperand>
           <orOp>
                <firstOperand>
                  <equalOp>
                        ...number1=10
                  </equalOp>
                </firstOperand>
                <secondOperand>
                  <equalOp>
                        ...number2=10
                  </equalOp>
                </secondOperand>
           </ orOp >
        </firstOperand>
        <secondOperand>
           <equalOp>
                ...number3=10
           </equalOp>
        </secondOperand>
   </ orOp >
  </firstOperand>
  <secondOperand>
        <equalOp>
          ...number4=10
        </equalOp>
  </secondOperand>
</ orOp >

And I have to do the same thing for any operation that contains a number
value. The exception is the case where we have (number > 5 AND number <
7). This will not directly translate to being able to do: (number1 > 5
OR number2 > 5 OR number3 > 5 OR number4 > 5) AND (number1 < 7 OR
number2 < 7 OR number3 < 7 OR number4 < 7) it has to be (number1 > 5 AND
number1 < 7) OR (number2 > 5 AND number2 < 7) OR (number3 > 5 AND
number3 < 7) OR (number4 > 5 AND number4 < 7)

So... I thought why not do a recursive loop to add these tags at the end
of each operation while using the iterative template you guys provided
earlier:

<xsl:template name="loop">
                <xsl:param name="a"/>
                <xsl:param name="times"/>
                <xsl:variable name="anchor" select="."/>
                <xsl:if test="$a &lt;= $times">
                        <xsl:if test="$a != $times">
                                <xsl:text
disable-output-escaping="yes">&lt;xqx:orOp
xmlns:xqx="http://www.w3.org/2005/XQueryX"; &gt;</xsl:text>
                                <xsl:text
disable-output-escaping="yes">&lt;xqx:firstOperand
xmlns:xqx="http://www.w3.org/2005/XQueryX"; &gt;</xsl:text>
                        </xsl:if>
                        <xsl:call-template name="loop">
                                <xsl:with-param name="a" select="$a +
1"/>
                                <xsl:with-param name="times"
select="$times"/>
                        </xsl:call-template>
                        <xsl:apply-templates select="$anchor">
                                <xsl:with-param name="iteration"
select="$a"/>
                        </xsl:apply-templates>
                        <xsl:if test="$a = $times">
                                <xsl:text
disable-output-escaping="yes">&lt;/xqx:firstOperand&gt;</xsl:text>
                                <xsl:text
disable-output-escaping="yes">&lt;xqx:secondOperand
xmlns:xqx="http://www.w3.org/2005/XQueryX"; &gt;</xsl:text>
                        </xsl:if>
                        <xsl:if test="$a = 1">
                                <xsl:text
disable-output-escaping="yes">&lt;/xqx:secondOperand&gt;</xsl:text>
                                <xsl:text
disable-output-escaping="yes">&lt;/xqx:orOp&gt;</xsl:text>
                        </xsl:if>
                        <xsl:if test="$a != $times">
                                <xsl:if test="$a != 1">
                                        <xsl:text
disable-output-escaping="yes">&lt;/xqx:secondOperand&gt;</xsl:text>
                                        <xsl:text
disable-output-escaping="yes">&lt;/xqx:orOp&gt;</xsl:text>
                                        <xsl:text
disable-output-escaping="yes">&lt;/xqx:firstOperand&gt;</xsl:text>
                                        <xsl:text
disable-output-escaping="yes">&lt;xqx:secondOperand
xmlns:xqx="http://www.w3.org/2005/XQueryX"; &gt;</xsl:text>
                                </xsl:if>
                        </xsl:if>
                </xsl:if>
        </xsl:template>

As you can see, I'm a procedural language developer, but I couldn't
think of a better way to do it. 

p.s. Sorry for making this so very long, but you did ask. :) And XQueryX
is not the best thing to work with, but it does work.

Roshan Punnoose
Phone: 301-497-6039

-----Original Message-----
From: Abel Braaksma [mailto:abel(_dot_)online(_at_)xs4all(_dot_)nl] 
Sent: Wednesday, January 31, 2007 9:13 AM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] Simple Question

Punnoose, Roshan wrote:
Thanks for the replies. I'm better understanding how XSLT works and
with
a little help able to get this to work:

<xsl:if test="$a != $times">
              <xsl:text
disable-output-espacing="yes">&lt;xqx:orOp&gt;</xsl:text>
                      ...
      </xsl:if>

Of course, there are problems in this too, but I'm working them out.

The reason I had to do it this way is because I'm working on a
recursive
loop that prints out a binary node tree, which I sort of needed this
for. (Though there probably is a way to do it a little cleaner.)

Regardless of your original problem, this is not the way to do it, and 
it won't work the way you intend either. There are ways to output 
non-xml text in an xml serialized output stream, and the preferred way 
with XSLT 2 is character-maps (but still, you can't output characters 
that cannot be represented in XML).

If you really have no need for <xqx:orOp>... </xqx:orOp> (nodes) but 
instead <xqx:orOp>...<xqx:otherOp> (text) you should consider another 
solution, like using output-method 'text'. This also prevents you from 
falling into the trap of creating nodes, when you mean the text (which 
looks like nodes when serialized, but really aren't), because nodes are 
not serialized in with the text-method (only the 'value-of' value of the

nodes).

Please inform us a bit deeper of the target format that you are 
creating. If it is XML, you must choose another way, if it is text that 
resembles XML, you may want to use XSLT in text-mode or another
language.

-- Abel


--~------------------------------------------------------------------
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>
--~--

<Prev in Thread] Current Thread [Next in Thread>