XQuery to Filter Elements

Discussion in 'XML' started by Zach Brown, Aug 16, 2007.

  1. Zach Brown

    Zach Brown Guest

    I'm totally stuck on this... I've got an xml fragment that looks like:

    <profile id="1">
    <meta>
    <groupID>100</groupID>
    </meta>
    <data>
    <field id="businessStage" date="8/15/2007">Shipping Product</field>
    <field id="businessStage" date="8/14/2007">Development</field>
    <field id="businessStage" date="8/13/2007">Research</field>
    <field id="ticker" date="8/15/2007">MyTICK</field>
    <field id="ticker" date="5/15/2005>TICK</field
    </data>
    </profile>

    And, i was hoping that i could write an xquery expression that would select
    basically the whole document minus any fields whose date didn't match
    "8/15/2007" resulting in this:

    <profile id="1">
    <meta>
    <groupID>100</groupID>
    </meta>
    <data>
    <field id="businessStage" date="8/15/2007">Shipping Product</field>
    <field id="ticker" date="8/15/2007">MyTICK</field>
    </data>
    </profile>

    Basically where I'm at now i either get the whole document returned or just
    the fields. Clearly I'm just starting out with experimenting with XQuery
    but i'm totally stuck trying to do what I thought was going to be an easy
    task.

    Any help or thoughts on this would be super appreciated.

    Regards,
    Zach
     
    Zach Brown, Aug 16, 2007
    #1
    1. Advertising

  2. Zach Brown

    Pavel Lepin Guest

    Zach Brown <> wrote in
    <D8Mwi.61895$fJ5.36078@pd7urf1no>:
    > <profile id="1">
    > <meta>
    > <groupID>100</groupID>
    > </meta>
    > <data>
    > <field id="businessStage" date="8/15/2007">Shipping
    > Product</field> <field id="businessStage"
    > date="8/14/2007">Development</field> <field
    > id="businessStage" date="8/13/2007">Research</field>
    > <field id="ticker" date="8/15/2007">MyTICK</field>
    > <field id="ticker" date="5/15/2005>TICK</field
    > </data>
    > </profile>
    >
    > And, i was hoping that i could write an xquery expression
    > that would select basically the whole document minus any
    > fields whose date didn't match "8/15/2007"


    So what's the problem? Process all the nodes recursively,
    omitting the ones that fit your criteria:

    declare function local:filter($node as node())
    {
    if (local:check($node))
    then
    if ($node[self::element()])
    then
    element { name($node) } { local:recurse($node) }
    else
    if ($node[self::document-node()])
    then document { local:recurse($node) }
    else $node
    else ()
    } ;

    declare function local:recurse($node as node())
    {
    for $child in ($node/@*|$node/node())
    return local:filter($child)
    } ;

    declare function local:check($node as node())
    {
    if ($node[self::field and @date!='8/15/2007'])
    then false() else true()
    } ;

    let $a := fn:doc('filter.xml')
    return local:filter($a)

    --
    "Patience is a minor form of despair, disguised as
    virtue." -- Ambrose Bierce
     
    Pavel Lepin, Aug 16, 2007
    #2
    1. Advertising

  3. Zach Brown

    Zach Brown Guest

    Wow. I've only been working around with xquery for the last week. For some
    reason, all the stuff that i've managed to find not once mentioned user
    defined functions. Powerful.

    Thanks for this Pavel. I appreciate it. Sometimes the biggest challenge
    when looking for an answer in a new technology is understanding what to
    ask... Thanks again.

    Regards,
    Zach

    "Pavel Lepin" <> wrote in message
    news:fa0to6$mkb$...
    >
    > Zach Brown <> wrote in
    > <D8Mwi.61895$fJ5.36078@pd7urf1no>:
    >> <profile id="1">
    >> <meta>
    >> <groupID>100</groupID>
    >> </meta>
    >> <data>
    >> <field id="businessStage" date="8/15/2007">Shipping
    >> Product</field> <field id="businessStage"
    >> date="8/14/2007">Development</field> <field
    >> id="businessStage" date="8/13/2007">Research</field>
    >> <field id="ticker" date="8/15/2007">MyTICK</field>
    >> <field id="ticker" date="5/15/2005>TICK</field
    >> </data>
    >> </profile>
    >>
    >> And, i was hoping that i could write an xquery expression
    >> that would select basically the whole document minus any
    >> fields whose date didn't match "8/15/2007"

    >
    > So what's the problem? Process all the nodes recursively,
    > omitting the ones that fit your criteria:
    >
    > declare function local:filter($node as node())
    > {
    > if (local:check($node))
    > then
    > if ($node[self::element()])
    > then
    > element { name($node) } { local:recurse($node) }
    > else
    > if ($node[self::document-node()])
    > then document { local:recurse($node) }
    > else $node
    > else ()
    > } ;
    >
    > declare function local:recurse($node as node())
    > {
    > for $child in ($node/@*|$node/node())
    > return local:filter($child)
    > } ;
    >
    > declare function local:check($node as node())
    > {
    > if ($node[self::field and @date!='8/15/2007'])
    > then false() else true()
    > } ;
    >
    > let $a := fn:doc('filter.xml')
    > return local:filter($a)
    >
    > --
    > "Patience is a minor form of despair, disguised as
    > virtue." -- Ambrose Bierce
     
    Zach Brown, Aug 16, 2007
    #3
  4. Zach Brown

    Pavel Lepin Guest

    Please don't top post.

    Zach Brown <> wrote in
    <pI0xi.63926$fJ5.31293@pd7urf1no>:
    > "Pavel Lepin" <> wrote in message
    > news:fa0to6$mkb$...
    >> Zach Brown <> wrote in
    >> <D8Mwi.61895$fJ5.36078@pd7urf1no>:
    >>> <profile id="1">
    >>> <meta>
    >>> <groupID>100</groupID>
    >>> </meta>
    >>> <data>
    >>> <field id="businessStage" date="8/15/2007">Shipping
    >>> Product</field> <field id="businessStage"
    >>> date="8/14/2007">Development</field> <field
    >>> id="businessStage" date="8/13/2007">Research</field>
    >>> <field id="ticker" date="8/15/2007">MyTICK</field>
    >>> <field id="ticker" date="5/15/2005>TICK</field
    >>> </data>
    >>> </profile>
    >>>
    >>> And, i was hoping that i could write an xquery
    >>> expression that would select basically the whole
    >>> document minus any fields whose date didn't match
    >>> "8/15/2007"

    >>
    >> So what's the problem? Process all the nodes recursively,
    >> omitting the ones that fit your criteria:


    [snip]

    > I've only been working around with xquery for the last
    > week.


    It's the second XQuery I've ever written, so 'only last
    week' sounds like an awful lot of time to do some reading
    to me.

    > For some reason, all the stuff that i've managed to find
    > not once mentioned user defined functions. Powerful.


    You've been reading the wrong stuff then. The XQuery spec is
    reasonably good as a reference, and definitely worth
    skimming over. If that's too hard for you, I'm fairly
    certain IBM's developerWorks has some good introductory
    reading in its XQuery library:

    http://www.ibm.com/developerworks/xml

    --
    "Patience is a minor form of despair, disguised as
    virtue." -- Ambrose Bierce
     
    Pavel Lepin, Aug 17, 2007
    #4
  5. Zach Brown

    Zach Brown Guest

    > Please don't top post.

    I top posted because my comment was no longer relevant to the initial
    question and was just a reflection. Don't make people scroll all the way to
    the bottom of a post if the data in the post in no longer relevant to the
    current threads voice. Just like the body was removed to clean up the
    document because it's no longer relevant to "this" discussion.

    Regards,
    Zach Brown
     
    Zach Brown, Aug 18, 2007
    #5
  6. Zach Brown

    Zach Brown Guest

    "Pavel Lepin" <> wrote in message
    news:fa0to6$mkb$...
    >
    > Zach Brown <> wrote in
    > <D8Mwi.61895$fJ5.36078@pd7urf1no>:
    >> <profile id="1">
    >> <meta>
    >> <groupID>100</groupID>
    >> </meta>
    >> <data>
    >> <field id="businessStage" date="8/15/2007">Shipping
    >> Product</field> <field id="businessStage"
    >> date="8/14/2007">Development</field> <field
    >> id="businessStage" date="8/13/2007">Research</field>
    >> <field id="ticker" date="8/15/2007">MyTICK</field>
    >> <field id="ticker" date="5/15/2005>TICK</field
    >> </data>
    >> </profile>
    >>
    >> And, i was hoping that i could write an xquery expression
    >> that would select basically the whole document minus any
    >> fields whose date didn't match "8/15/2007"

    >
    > So what's the problem? Process all the nodes recursively,
    > omitting the ones that fit your criteria:
    >
    > declare function local:filter($node as node())
    > {
    > if (local:check($node))
    > then
    > if ($node[self::element()])
    > then
    > element { name($node) } { local:recurse($node) }
    > else
    > if ($node[self::document-node()])
    > then document { local:recurse($node) }
    > else $node
    > else ()
    > } ;
    >
    > declare function local:recurse($node as node())
    > {
    > for $child in ($node/@*|$node/node())
    > return local:filter($child)
    > } ;
    >
    > declare function local:check($node as node())
    > {
    > if ($node[self::field and @date!='8/15/2007'])
    > then false() else true()
    > } ;
    >
    > let $a := fn:doc('filter.xml')
    > return local:filter($a)
    >
    > --
    > "Patience is a minor form of despair, disguised as
    > virtue." -- Ambrose Bierce


    Got this implemented and this worked great BTW. Thanks again.

    Best,
    Zach
     
    Zach Brown, Aug 18, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jeff Kish
    Replies:
    11
    Views:
    812
    Jeff Kish
    Oct 21, 2004
  2. Bob
    Replies:
    0
    Views:
    450
  3. Replies:
    7
    Views:
    468
  4. zax75
    Replies:
    1
    Views:
    1,123
  5. kishjeff
    Replies:
    2
    Views:
    797
    kishjeff
    Dec 17, 2008
Loading...

Share This Page