Is there a way to use filtering in E4X with hyphenated XML elements?

Discussion in 'Javascript' started by ten8ciousb, Jan 23, 2009.

  1. ten8ciousb

    ten8ciousb Guest

    Tried this over at mozilla.dev.tech but didn't get any bites.
    I know can return a list of nodes, but I want to get a specific
    value.

    given this xml
    var phoneList = <table>
    <row>
    <COMPANY-NAME>DUNDER MIFFLIN</COMPANY-NAME>
    <EMPLOYEE-NAME>Jim Halpert</EMPLOYEE-NAME>
    <EMPLOYEE-PHONE>555-555-5555</EMPLOYEE-PHONE>
    </row>
    <row>
    <COMPANY-NAME>INNOTECH</COMPANY-NAME>
    <EMPLOYEE-NAME>Peter Gibbons</EMPLOYEE-NAME>
    <EMPLOYEE-PHONE>555-444-4444</EMPLOYEE-PHONE>
    </row>
    <row>
    <COMPANY-NAME>DUNDER MIFFLIN</COMPANY-NAME>
    <EMPLOYEE-NAME>Dwight Schroot</EMPLOYEE-NAME>
    <EMPLOYEE-PHONE>555-555-5550</EMPLOYEE-PHONE>
    </row>

    </table>;

    if I want to get only the DUNDER MIFFLIN records, I can't use
    phoneList..row.(COMPANY-NAME == "DUNDER MIFFLIN")
    because the hyphen is used as a minus and I get an error about NAME
    not
    being defined or something.

    I know that I can get a list of all the "COMPANY-NAME" nodes using
    phoneList..row["COMPANY-NAME"];
    -or-
    phoneList...row.descendants("COMPANY-NAME");

    those both return:
    <COMPANY-NAME>DUNDER MIFFLIN</COMPANY-NAME>
    <COMPANY-NAME>INNOTECH</COMPANY-NAME>
    <COMPANY-NAME>DUNDER MIFFLIN</COMPANY-NAME>

    Is there a way to filter the list? How can I just the DUNDER MIFFLIN
    list? i.e., how can I do this?
    phoneList..row.(COMPANY-NAME == "DUNDER MIFFLIN");

    And to take it a step further. Just get the list of Dunder Mifflin
    employees. How
    phoneList..row.(COMPANY-NAME == "DUNDER MIFFLIN").EMPLOYEE-NAME;

    and ultimately the phone number for a specific employee at a specific
    company.
    phoneList..row.(COMPANY-NAME == "DUNDER MIFFLIN" && EMPLOYEE-NAME ==
    "Jim Halpert").EMPLOYEE-PHONE;


    I have tried variations but haven't found one that let's me filter on
    the content
     
    ten8ciousb, Jan 23, 2009
    #1
    1. Advertising

  2. ten8ciousb wrote:

    > Tried this over at mozilla.dev.tech but didn't get any bites.
    > I know can return a list of nodes, but I want to get a specific
    > value.
    >
    > given this xml
    > var phoneList = <table>
    > <row>
    > <COMPANY-NAME>DUNDER MIFFLIN</COMPANY-NAME>
    > <EMPLOYEE-NAME>Jim Halpert</EMPLOYEE-NAME>
    > <EMPLOYEE-PHONE>555-555-5555</EMPLOYEE-PHONE>
    > </row>
    > <row>
    > <COMPANY-NAME>INNOTECH</COMPANY-NAME>
    > <EMPLOYEE-NAME>Peter Gibbons</EMPLOYEE-NAME>
    > <EMPLOYEE-PHONE>555-444-4444</EMPLOYEE-PHONE>
    > </row>
    > <row>
    > <COMPANY-NAME>DUNDER MIFFLIN</COMPANY-NAME>
    > <EMPLOYEE-NAME>Dwight Schroot</EMPLOYEE-NAME>
    > <EMPLOYEE-PHONE>555-555-5550</EMPLOYEE-PHONE>
    > </row>
    >
    > </table>;
    >
    > if I want to get only the DUNDER MIFFLIN records, I can't use
    > phoneList..row.(COMPANY-NAME == "DUNDER MIFFLIN")
    > because the hyphen is used as a minus and I get an error about NAME
    > not being defined


    Yes, `-' is an operator.

    > Is there a way to filter the list? How can I just the DUNDER MIFFLIN
    > list?


    A verb here.

    > i.e., how can I do this?


    With iteration over the nodes, or with XPath filtering and iteration over
    the result. For example the latter:

    var d = (new DOMParser()).parseFromString(phoneList, "text/xml");
    if (!d) { /* gauntlet: error status */ }

    var res = d.evaluate(
    '//row/COMPANY-NAME[text() = "DUNDER MIFFLIN"]/following-sibling::*]',
    d,
    null,
    ...,
    null);

    // depending on ... as fourth argument, either
    var e;
    while ((e = res.iterateNext())
    {
    // ... e ...
    }

    // or
    for (var i = 0, len = res.snapshotLength; i < len; i++)
    {
    // ... res.snapshotItem(i) ...
    }

    This assumes that the COMPANY-NAME element node is the first sibling. WFM
    in Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.5) Gecko/2008122011
    Iceweasel/3.0.5 (Debian-3.0.5-1).

    You might want to use all-lowercase element types without hyphen in it
    instead, like

    <companies>
    <company>
    <name>Dunder Mifflin</name>
    <employees>
    <employee>
    <name>Jim Halpert</name>
    <phone>555-555-5555</phone>
    </employee>
    ...
    <employees>
    </company>
    ...
    </companies>

    Or consider JSON.

    RTFM, STFW:

    <https://developer.mozilla.org/En/E4X>
    <https://developer.mozilla.org/En/DOMParser>
    <https://developer.mozilla.org/En/DOM/Document.evaluate>
    <http://www.w3.org/TR/1999/REC-xpath-19991116/>
    <http://json.org/>


    HTH

    PointedEars
     
    Thomas 'PointedEars' Lahn, Jan 23, 2009
    #2
    1. Advertising

  3. ten8ciousb

    ten8ciousb Guest

    Re: Is there a way to use filtering in E4X with hyphenated XMLelements?

    First I apologize most sincerely for the incomplete sentences. I know
    that can make it difficult to understand the questions when you have
    to fill in the blanks.
    Also thank you for the detailed reply and the RTFM and STFW
    suggestions.
    I guess I wasn't clear in my question.

    With E4X, I can filter the results, saying I want a list of employees
    where the value of company_name is "DUNDER MIFFLIN" like
    var employees = phoneList..row.(company_name == "DUNDER
    MIFFLIN").EMPLOYEE-NAME;

    However, if the element contains a hyphen instead of an underscore,
    i.e. company-name, that syntax won't work.
    this: var employees = phoneList..row.(company-name == "DUNDER
    MIFFLIN").EMPLOYEE-NAME;
    results in a reference error name is undefined.

    What I wanted to know is if there was a syntax in E4X for this type of
    filtering with elements containing hyphens.
    If I understand your response correctly, the answer is "No. But,
    there are other ways to do it."
     
    ten8ciousb, Jan 23, 2009
    #3
  4. ten8ciousb wrote:

    > With E4X, I can filter the results, saying I want a list of employees
    > where the value of company_name is "DUNDER MIFFLIN" like
    > var employees = phoneList..row.(company_name == "DUNDER
    > MIFFLIN").EMPLOYEE-NAME;
    >
    > However, if the element contains a hyphen instead of an underscore,
    > i.e. company-name, that syntax won't work.
    > this: var employees = phoneList..row.(company-name == "DUNDER
    > MIFFLIN").EMPLOYEE-NAME;
    > results in a reference error name is undefined.
    >
    > What I wanted to know is if there was a syntax in E4X for this type of
    > filtering with elements containing hyphens.
    > If I understand your response correctly, the answer is "No. But,
    > there are other ways to do it."


    phoneList..row.descendants("COMPANY-NAME")

    See ECMA-357. HTH and let us know your solution, please.


    PointedEars
     
    Thomas 'PointedEars' Lahn, Jan 23, 2009
    #4
  5. ten8ciousb wrote:

    > var phoneList = <table>
    > <row>
    > <COMPANY-NAME>DUNDER MIFFLIN</COMPANY-NAME>
    > <EMPLOYEE-NAME>Jim Halpert</EMPLOYEE-NAME>
    > <EMPLOYEE-PHONE>555-555-5555</EMPLOYEE-PHONE>
    > </row>
    > <row>
    > <COMPANY-NAME>INNOTECH</COMPANY-NAME>
    > <EMPLOYEE-NAME>Peter Gibbons</EMPLOYEE-NAME>
    > <EMPLOYEE-PHONE>555-444-4444</EMPLOYEE-PHONE>
    > </row>
    > <row>
    > <COMPANY-NAME>DUNDER MIFFLIN</COMPANY-NAME>
    > <EMPLOYEE-NAME>Dwight Schroot</EMPLOYEE-NAME>
    > <EMPLOYEE-PHONE>555-555-5550</EMPLOYEE-PHONE>
    > </row>
    >
    > </table>;
    >
    > if I want to get only the DUNDER MIFFLIN records, I can't use
    > phoneList..row.(COMPANY-NAME == "DUNDER MIFFLIN")
    > because the hyphen is used as a minus and I get an error about NAME
    > not
    > being defined or something.


    I think with Spidermonkey's E4X implementation you can do

    phoneList.row.(function::child('COMPANY-NAME') == 'DUNDER MIFFLIN')

    I don't know whether Rhino's E4X has that special 'function::' namespace
    to access methods.

    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
     
    Martin Honnen, Jan 23, 2009
    #5
  6. Martin Honnen wrote:

    > ten8ciousb wrote:
    >> var phoneList = <table>
    >> <row>
    >> <COMPANY-NAME>DUNDER MIFFLIN</COMPANY-NAME>
    >> <EMPLOYEE-NAME>Jim Halpert</EMPLOYEE-NAME>
    >> <EMPLOYEE-PHONE>555-555-5555</EMPLOYEE-PHONE>
    >> </row>
    >> <row>
    >> <COMPANY-NAME>INNOTECH</COMPANY-NAME>
    >> <EMPLOYEE-NAME>Peter Gibbons</EMPLOYEE-NAME>
    >> <EMPLOYEE-PHONE>555-444-4444</EMPLOYEE-PHONE>
    >> </row>
    >> <row>
    >> <COMPANY-NAME>DUNDER MIFFLIN</COMPANY-NAME>
    >> <EMPLOYEE-NAME>Dwight Schroot</EMPLOYEE-NAME>
    >> <EMPLOYEE-PHONE>555-555-5550</EMPLOYEE-PHONE>
    >> </row>
    >>
    >> </table>;
    >>
    >> if I want to get only the DUNDER MIFFLIN records, I can't use
    >> phoneList..row.(COMPANY-NAME == "DUNDER MIFFLIN")
    >> because the hyphen is used as a minus and I get an error about NAME
    >> not
    >> being defined or something.

    >
    > I think with Spidermonkey's E4X implementation you can do
    >
    > phoneList.row.(function::child('COMPANY-NAME') == 'DUNDER MIFFLIN')
    >
    > I don't know whether Rhino's E4X has that special 'function::' namespace
    > to access methods.


    I was to suggest something along

    [x for each (x in phoneList.row["COMPANY-NAME"]) if (x == "DUNDER MIFFLIN")]

    But yours is better as it gets the rows. Unfortunately, I could not come up
    with a filtering predicate that filters for element content:

    phoneList.row["COMPANY-NAME"].(x == "DUNDER MIFFLIN")

    Suggestions, except the above?


    PointedEars
     
    Thomas 'PointedEars' Lahn, Jan 23, 2009
    #6
  7. ten8ciousb

    ten8ciousb Guest

    Re: Is there a way to use filtering in E4X with hyphenated XMLelements?

    Thank you for the replies.

    phoneList.row.(function::child('COMPANY-NAME') == 'DUNDER MIFFLIN')
    does work if using SpiderMonkey.
    It does not appear to work using Rhino. (Rhino 1.7 release 2) which
    is what I'm trying to do.
    just trying to open the script in the debugger give the error :
    missing ( before function parameters.
    js: thisRow = phoneList.row.(function::child('COMPANY-NAME') ==
    'DUNDER MIFFLIN');
     
    ten8ciousb, Jan 26, 2009
    #7
  8. Re: Is there a way to use filtering in E4X with hyphenated XML elements?

    ten8ciousb wrote:
    > Thank you for the replies.


    You're welcome.

    > phoneList.row.(function::child('COMPANY-NAME') == 'DUNDER MIFFLIN')
    > does work if using SpiderMonkey.
    > It does not appear to work using Rhino. (Rhino 1.7 release 2) which
    > is what I'm trying to do.
    > just trying to open the script in the debugger give the error :
    > missing ( before function parameters.
    > js: thisRow = phoneList.row.(function::child('COMPANY-NAME') ==
    > 'DUNDER MIFFLIN');


    I have been thinking about my approach; try this:

    var filtered = [
    r for each (r in phoneList.row)
    if (r["COMPANY-NAME"] == "DUNDER MIFFLIN")
    ];

    Not standards-compliant (requires JavaScript 1.7 Array comprehension), but
    it worksforme (in SpiderMonkey). Your Rhino version indicates it should
    work there, too. If not, this should work:

    var filtered = [];
    for each (var r in phoneList.row)
    {
    if (r["COMPANY-NAME"] == "DUNDER MIFFLIN") filtered.push(r);
    }


    Regards,

    PointedEars
     
    Thomas 'PointedEars' Lahn, Jan 26, 2009
    #8
    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. Joris Gillis
    Replies:
    2
    Views:
    1,567
    Joris Gillis
    Jun 16, 2006
  2. Replies:
    2
    Views:
    591
  3. Bob Tinsman
    Replies:
    1
    Views:
    99
    Martin Honnen
    Mar 15, 2006
  4. Bob Tinsman

    E4X: can't use "delete" with filter

    Bob Tinsman, Mar 14, 2006, in forum: Javascript
    Replies:
    2
    Views:
    101
    Martin Honnen
    Mar 15, 2006
  5. Replies:
    4
    Views:
    146
    Martin Honnen
    Apr 23, 2006
Loading...

Share This Page