Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > Is there a way to use filtering in E4X with hyphenated XML elements?

Reply
Thread Tools

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

 
 
ten8ciousb
Guest
Posts: n/a
 
      01-23-2009
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
 
Reply With Quote
 
 
 
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      01-23-2009
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
 
Reply With Quote
 
 
 
 
ten8ciousb
Guest
Posts: n/a
 
      01-23-2009
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."


 
Reply With Quote
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      01-23-2009
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
 
Reply With Quote
 
Martin Honnen
Guest
Posts: n/a
 
      01-23-2009
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/
 
Reply With Quote
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      01-23-2009
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
 
Reply With Quote
 
ten8ciousb
Guest
Posts: n/a
 
      01-26-2009
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');

 
Reply With Quote
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      01-26-2009
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
soap request includes a hyphenated field, don't know how to set it straycat000@yahoo.com Python 2 03-27-2009 08:22 AM
E4X "ECMAScript For XML" Patrick.O.Ige ASP .Net 0 01-23-2007 01:25 AM
insert E4X XML tree inside existing DOM tree Joris Gillis XML 2 06-16-2006 08:30 PM
E4X: can't use "delete" with filter Bob Tinsman Javascript 2 03-15-2006 04:52 PM
E4X/Firefox 1.5: problem using default xml namespace Bob Tinsman Javascript 1 03-15-2006 03:52 PM



Advertisments