[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] RE: Simple Question
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 <= $times"> <xsl:if test="$a != $times"> <xsl:text disable-output-escaping="yes"><xqx:orOp xmlns:xqx="http://www.w3.org/2005/XQueryX" ></xsl:text> <xsl:text disable-output-escaping="yes"><xqx:firstOperand xmlns:xqx="http://www.w3.org/2005/XQueryX" ></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"></xqx:firstOperand></xsl:text> <xsl:text disable-output-escaping="yes"><xqx:secondOperand xmlns:xqx="http://www.w3.org/2005/XQueryX" ></xsl:text> </xsl:if> <xsl:if test="$a = 1"> <xsl:text disable-output-escaping="yes"></xqx:secondOperand></xsl:text> <xsl:text disable-output-escaping="yes"></xqx:orOp></xsl:text> </xsl:if> <xsl:if test="$a != $times"> <xsl:if test="$a != 1"> <xsl:text disable-output-escaping="yes"></xqx:secondOperand></xsl:text> <xsl:text disable-output-escaping="yes"></xqx:orOp></xsl:text> <xsl:text disable-output-escaping="yes"></xqx:firstOperand></xsl:text> <xsl:text disable-output-escaping="yes"><xqx:secondOperand xmlns:xqx="http://www.w3.org/2005/XQueryX" ></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.online@xxxxxxxxx] Sent: Wednesday, January 31, 2007 9:13 AM To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx Subject: Re: 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"><xqx:orOp></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
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|