XPath predicate problem

Discussion in 'XML' started by Ziphims, Jan 11, 2008.

  1. Ziphims

    Ziphims Guest

    I'm having a problem with XPath's predicate. This is the data I'm
    dealing right now:


    <?xml version="1.0" encoding="UTF-8"?>
    <EMPLOYEE ID="2">
    <NAME Src="DB">Alan Smith</NAME>
    <SEX Src="DB">M</SEX>
    <ADDRESSES>
    <ADDRESSITEM EMPID="2">
    <NAME Src="DB">Apartment</NAME>
    <ADDRESS Src="DB">Orchard Rd.</ADDRESS>
    <POSTCODE Src="DB">110000</POSTCODE>
    </ADDRESSITEM>
    </ADDRESSES>
    <BIRTHDATE Src="DB">210038400</BIRTHDATE>
    <BIRTHLOCATION Src="DB">Jakarta</BIRTHLOCATION>
    <RELATEDDATA>
    <RELATIONTYPE ID="3">
    <NAME Src="DB">Husband</NAME>
    <NAME_R Src="DB">Wife</NAME_R>
    </RELATIONTYPE>
    <RELATIONTYPE ID="4">
    <NAME Src="DB">Friend</NAME>
    <NAME_R Src="DB"></NAME_R>
    </RELATIONTYPE>
    <PEOPLE PID="3">
    <NAME Src="DB">Elisha Sue</NAME>
    <SEX Src="DB">F</SEX>
    </PEOPLE>
    <PEOPLE PID="10">
    <NAME Src="DB">Robert Thompson</NAME>
    <SEX Src="DB">M</SEX>
    </PEOPLE>
    <PEOPLE PID="13">
    <NAME Src="DB">Steven Richard</NAME>
    <SEX Src="DB">M</SEX>
    </PEOPLE>
    </RELATEDDATA>
    <PHONENUMBERS>
    <NUMBERITEM EMPID="2">
    <NAME Src="DB">Cellphone (Work)</NAME>
    <NUMBER Src="DB">0835 545856425</NUMBER>
    </NUMBERITEM>
    <NUMBERITEM EMPID="2">
    <NAME Src="DB">Home (Fax)</NAME>
    <NUMBER Src="DB">5748963</NUMBER>
    </NUMBERITEM>
    </PHONENUMBERS>
    <RELATIONSHIPS>
    <RELITEM>
    <PEOPLE1 Src="DB">2</PEOPLE1>
    <PEOPLE2 Src="DB">3</PEOPLE2>
    <RELTYPE Src="DB">3</RELTYPE>
    </RELITEM>
    <RELITEM>
    <PEOPLE1 Src="DB">2</PEOPLE1>
    <PEOPLE2 Src="DB">10</PEOPLE2>
    <RELTYPE Src="DB">4</RELTYPE>
    </RELITEM>
    </RELATIONSHIPS>
    </EMPLOYEE>



    What I'm trying to do is to get the NAME of a PEOPLE element (part of
    RELATEDDATA element) having PID of PEOPLE2 element under a RELITEM
    element. So far the only thing that is close to what I want is this
    expression:

    (using RELITEM element as pivot point)
    ancestor::*/RELATEDDATA//NAME[parent::pEOPLE/@PID = //PEOPLE2]/
    parent::pEOPLE

    But as you can guess, it select two PEOPLE because I'm using "//". The
    thing is, I'm parsing this document for a program (using libxml2) and
    it evaluate one RELITEM element at a time. So what I want is to use
    the currently 'selected' RELITEM and get PEOPLE element based on
    PEOPLE2 element (under the currently 'selected' RELITEM) value.

    I've set the pivot element in libxml2 to use the currently 'selected'
    RELITEM but I'm not getting any result from this expression:

    ancestor::*/RELATEDDATA//NAME[parent::pEOPLE/@PID = /PEOPLE2]

    All of this led me to a question: Is it possible to use pivot element
    in libxml inside a predicate? If yes, how?

    I'm open to any suggestion, word of wisdom, advice, link, basically
    anything to explain this.
     
    Ziphims, Jan 11, 2008
    #1
    1. Advertising

  2. Ziphims

    TOUDIdel Guest

    Uzytkownik "Ziphims" <> napisal w wiadomosci
    news:...
    > (using RELITEM element as pivot point)
    > ancestor::*/RELATEDDATA//NAME[parent::pEOPLE/@PID =
    > //PEOPLE2]/parent::pEOPLE
    > ancestor::*/RELATEDDATA//NAME[parent::pEOPLE/@PID = /PEOPLE2]


    If RELITEM is your context node why do you use //PEOPLE2 or /PEOPLE2 in test
    statement instead of PEOLPE2 (without any slashes) which are child nodes of
    your RELITEM context node?
    --
    td
    xmlguru.net
     
    TOUDIdel, Jan 11, 2008
    #2
    1. Advertising

  3. Ziphims

    Pavel Lepin Guest

    TOUDIdel <> wrote in
    <fm7ssv$nd8$>:
    > Uzytkownik "Ziphims" <> napisal:
    >> (using RELITEM element as pivot point)
    >> ancestor::*/RELATEDDATA//NAME[parent::pEOPLE/@PID =
    >> //PEOPLE2]/parent::pEOPLE
    >> ancestor::*/RELATEDDATA//NAME[parent::pEOPLE/@PID =
    >> /PEOPLE2]

    >
    > If RELITEM is your context node why do you use //PEOPLE2
    > or /PEOPLE2 in test statement instead of PEOLPE2 (without
    > any slashes) which are child nodes of your RELITEM context
    > node?


    Because 'PEOPLE2' in that predicate would refer to PEOPLE2
    element children of NAME element referred to in this
    location step (of which there are none, obviously), and not
    to PEOPLE2 children of context node. What the OP tried
    doesn't work either, of course. You gotta generate XPath1
    expressions on the fly to do that.

    Just a friendly observation: the invariably flawed bits of
    advice you post on this group produce a somewhat awkward
    impression taken together with the domain name of the
    website you advertise in your sig. I mean, eh, guru?..
    Ro-oi-ight...

    --
    ....also, I submit that we all must honourably commit seppuku
    right now rather than serve the Dark Side by producing the
    HTML 5 spec.
     
    Pavel Lepin, Jan 11, 2008
    #3
  4. Build it up in stages, as with any other programming languages

    >NAME of a PEOPLE element (part of
    > RELATEDDATA element) having the
    >PID of PEOPLE2 element under a RELITEM
    > element (using RELITEM element as pivot point)


    Find the PEOPLE elements. More explicit paths are faster so...
    /EMPLOYEE/RELATEDDATA/PEOPLE

    Add a predicate to select the one which has the desired PID.
    The PEOPLE2 element doesn't carry a PID attribute, so I'm assuming its
    value is intended to be the PID. I'm also assuming that by "pivot point"
    you mean "current element". If so, this is simply the value of the
    PEOPLE2 element.
    /EMPLOYEE/RELATEDDATA/PEOPLE[@PID=current()/PEOPLE2]
    The trick here is the use of current(), which says we want the PEOPLE2
    child of the current node, NOT of the node we're applying the predicate to.

    Now get the NAME child of that selected entry:
    /EMPLOYEE/RELATEDDATA/PEOPLE[@PID=current()/PEOPLE2]/NAME












    So far the only thing that is close to what I want is this
    > expression:
    >
    > (using RELITEM element as pivot point)
    > ancestor::*/RELATEDDATA//NAME[parent::pEOPLE/@PID = //PEOPLE2]/
    > parent::pEOPLE
    >
    > But as you can guess, it select two PEOPLE because I'm using "//". The
    > thing is, I'm parsing this document for a program (using libxml2) and
    > it evaluate one RELITEM element at a time. So what I want is to use
    > the currently 'selected' RELITEM and get PEOPLE element based on
    > PEOPLE2 element (under the currently 'selected' RELITEM) value.
    >
    > I've set the pivot element in libxml2 to use the currently 'selected'
    > RELITEM but I'm not getting any result from this expression:
    >
    > ancestor::*/RELATEDDATA//NAME[parent::pEOPLE/@PID = /PEOPLE2]
    >
    > All of this led me to a question: Is it possible to use pivot element
    > in libxml inside a predicate? If yes, how?
    >
    > I'm open to any suggestion, word of wisdom, advice, link, basically
    > anything to explain this.



    --
    Joe Kesselman / Beware the fury of a patient man. -- John Dryden
     
    Joseph Kesselman, Jan 11, 2008
    #4
  5. Ziphims

    TOUDIdel Guest

    Uzytkownik "Pavel Lepin" <> napisal w wiadomosci
    news:fm7tuc$5a2$...
    > Because 'PEOPLE2' in that predicate would refer to PEOPLE2
    > element children of NAME element referred to in this
    > location step (of which there are none, obviously), and not
    > to PEOPLE2 children of context node. What the OP tried
    > doesn't work either, of course. You gotta generate XPath1
    > expressions on the fly to do that.


    yes you right of course. that statement's writing makes me fool; I always
    use current() function to avoid that kind mistakes.
    --
    td
    xmlguru.net
     
    TOUDIdel, Jan 11, 2008
    #5
  6. Actually, if you're working in pure XPath rather than XSLT, I'm not sure
    current() is available. If it isn't, you may need to pass the context
    node in as a variable (look at your XPath engine's documentation to see
    how to do this) and reference that variable from within the predicate.

    --
    Joe Kesselman / Beware the fury of a patient man. -- John Dryden
     
    Joseph Kesselman, Jan 11, 2008
    #6
  7. Ziphims

    P. Lepin Guest

    Joseph Kesselman wrote:
    > Actually, if you're working in pure XPath rather than XSLT, I'm not sure
    > current() is available.


    It isn't, current() is XSLT-specific, and is described in 12.4 of XSLT1.

    > If it isn't, you may need to pass the context node in as a variable (look
    > at your XPath engine's documentation to see how to do this) and reference
    > that variable from within the predicate.


    Note that as far as I can tell XPath variable binding is not a part of DOM
    API specs, therefore the details vary from parser to parser, although every
    XPath processor API's I've seen did it in a reasonably sensible way.

    Simply generating the expression on the fly is often the easiest solution,
    but, yeah, not one of the Best Practices by any stretch of imagination.

    --
    Presented in Brain Control where available.
     
    P. Lepin, Jan 12, 2008
    #7
    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. Sabba
    Replies:
    0
    Views:
    642
    Sabba
    May 9, 2006
  2. Replies:
    1
    Views:
    491
    Martin Honnen
    Feb 24, 2007
  3. Duncan Smith
    Replies:
    7
    Views:
    502
    Joseph Kesselman
    Mar 22, 2007
  4. Wabiloo
    Replies:
    1
    Views:
    857
    Martin Honnen
    Jan 25, 2008
  5. Phantom
    Replies:
    5
    Views:
    804
Loading...

Share This Page