xsl-list
[Top] [All Lists]

Re: Re: [xsl] XSLT Subtract function?

2007-04-13 10:06:14
On 4/13/07, cknell(_at_)onebox(_dot_)com <cknell(_at_)onebox(_dot_)com> wrote:
Thank you. I've visited the FSXL web site (http://fxsl.sourceforge.net/), but I don't see 
a reference to on the "Implemented Functions" list. Is there another web site 
with this information?
--
Charles Knell
cknell(_at_)onebox(_dot_)com - email

No.

One would notice that there are a lot of fles in the "Tests" directory named

  testFunc-<unctuin-name>.xsl

one of them is:

    testFunc-filter.xsl



So, for every function in FXSL there is at least one representative
working example/test in the Tests directory.

I have altered slightly the code of testFunc-filter.xsl to be closer
to your problem (the original code is commented out):

    testFunc-filter.xsl
===============
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:f="http://fxsl.sf.net/";
xmlns:myIsEven="myIsEven"
exclude-result-prefixes="f myIsEven"


 <xsl:import href="../f/func-filter.xsl"/>

 <!-- To be applied on ../data/numList.xml

      Expected result:
              Filtering by IsEven:
               02, 04, 06, 08, 10,

-->

 <xsl:output indent="yes" omit-xml-declaration="yes"/>

 <myIsEven:myIsEven/>

 <xsl:template match="/">
   <xsl:variable name="vIsEven" select="document('')/*/myIsEven:*[1]"/>

   Filtering by IsEven:

   <xsl:sequence select="f:filter(/*/*, $vIsEven)"/>
<!--
   <xsl:for-each select="f:filter(/*/*, $vIsEven)">
     <xsl:value-of select="concat(., ', ')"/>
   </xsl:for-each>
-->
 </xsl:template>

 <xsl:template name="myIsEven" match="*[namespace-uri()='myIsEven']"
  mode="f:FXSL">
   <xsl:param name="arg1"/>

   <xsl:if test="$arg1 mod 2 = 0">1</xsl:if>
 </xsl:template>
</xsl:stylesheet>


The result of applying this transformation on the recommended source xml:

numList.xml
==========
<nums>
 <num>01</num>
 <num>02</num>
 <num>03</num>
 <num>04</num>
 <num>05</num>
 <num>06</num>
 <num>07</num>
 <num>08</num>
 <num>09</num>
 <num>010</num>
</nums>


is:

   Filtering by IsEven:

   <num>02</num>
<num>04</num>
<num>06</num>
<num>08</num>
<num>010</num>


In this case one could totally eliminate the need to write their own
filtering function, by using the mod() operator directly.

Then the XPath expression to get the new document is simply:

               f:filter(/*/*, f:compose(f:not(), f:flip(f:mod(),2)))


and the complete xslt code is:


<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:f="http://fxsl.sf.net/";
exclude-result-prefixes="f"


 <xsl:import href="../f/func-filter.xsl"/>
 <xsl:import href="../f/func-Operators.xsl"/>
 <xsl:import href="../f/func-standardXpathFunctions.xsl"/>
 <xsl:import href="../f/func-flip.xsl"/>
 <xsl:import href="../f/func-compose.xsl"/>

 <!-- To be applied on ../data/numList.xml

      Expected result:
              Filtering by IsEven:
               02, 04, 06, 08, 10,

-->

 <xsl:output indent="yes" omit-xml-declaration="yes"/>

 <xsl:template match="/">
   Filtering by IsEven:


   <xsl:sequence select="f:filter(/*/*, f:compose(f:not(),
f:flip(f:mod(),2)))"/>
 </xsl:template>
</xsl:stylesheet>


Hope his helped.




--
Cheers,
Dimitre Novatchev
---------------------------------------
Truly great madness cannot be achieved without significant intelligence.
---------------------------------------
To invent, you need a good imagination and a pile of junk
-------------------------------------
You've achieved success in your field when you don't know whether what
you're doing is work or play







-----Original Message-----
From:     Dimitre Novatchev <dnovatchev(_at_)gmail(_dot_)com>
Sent:     Fri, 13 Apr 2007 08:43:48 -0700
To:       xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject:  Re: [xsl] XSLT Subtract function?

Do have a look at the

    filter()

functio in FXSL.



--
Cheers,
Dimitre Novatchev
---------------------------------------
Truly great madness cannot be achieved without significant intelligence.
---------------------------------------
To invent, you need a good imagination and a pile of junk
-------------------------------------
You've achieved success in your field when you don't know whether what
you're doing is work or play






On 4/13/07, cknell(_at_)onebox(_dot_)com <cknell(_at_)onebox(_dot_)com> wrote:
> Yesterday I was tasked to produce a list of records from an Oracle database 
where the result set contained rows where the value in one of the columns was not 
one of a long list. (Bear with me, please, we'll get to XSLT in a moment.)
>
> The problem was that the list of values to omit was simply too long for 
SQL*Plus. So I went to plan B. I selected all the rows from the table in question 
into an XML document. I prepared a second XML document that contained an element 
for each of the values to be omitted.
>
> I then wrote a stylesheet with this template:
>
> <xsl:template match="ROWSET">
>  <ROWSET>
>    <xsl:apply-templates select="ROW[not(CODE = $active-codes/ROWSET/ROW/CODE)]" 
/>
>  </ROWSET>
> </xsl:template>
>
> So the output contained all the ROW elements in the original document whose 
CODE child string value didn't match any of the CODE string values in the document 
containing the values I wanted to omit from the result.
>
> In short, I wanted to subtract the set of values contained in the second 
document from the first, resulting in a document containing only the non-matching 
values.
>
> After I finished, it occurred to me that this probably wasn't so unusual a 
need, and that probably someone had written a general-purpose function for this. 
What I had in mind is a function that would take four arguments:
>
> 1) A base document (base document) [$base]
> 2) A document containing the values to subtract from the base document 
(exemplar document) [$exemplar]
> 3) The XPath to the elment in the base document holding the values of 
interest. [$base-element]
> 4) The XPath to the element in the exemplar document holding the values of 
interest. [$list-element]
>
> The result would be a document with the same structure as the base document 
containing only those elements which didn't have a matching value.
>
> Here is an example of two documents:
>
> The base document:
>
> <?xml version="1.0"?>
> <grocery-list>
>  <item>apple</item>
>  <item>milk</item>
>  <item>cheese</item>
>  <item>coffee</item>
>  <item>asparagus</item>
> </grocery-list>
>
> The exemplar document:
>
> <?xml version="1.0"?>
> <inventory>
>  <sku>apple</sku>
>  <sku>pear</sku>
>  <sku>grapes</sku>
> </inventory>
>
> What I would like is a general-purpose function that would subtract those 
elements from the first document whose values matched the elements in the second.
>
> <grocery-list>
>  <item>milk</item>
>  <item>cheese</item>
>  <item>coffee</item>
>  <item>asparagus</item>
> </grocery-list>
>
> I've poked around on Google, but haven't found a useful was to compose the 
search. Does anyone on the list know of such a function or have you written one? I 
am reluctant to re-invent the wheel, particularly when mine is not likely to be as 
round and smooth as an existing one.
>
> Thanks.
>
> --
> Charles Knell
> cknell(_at_)onebox(_dot_)com - email
>
> --~------------------------------------------------------------------
> 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>
--~--

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