JavaScript / Rhino: Can I use a regular expression in an E4X query to select certain nodes only?
-
22-09-2019 - |
문제
I'm working on Rhino (Mirth), and I've got to process / parse an XML with the following structure:
<root>
<row>
<foo-1 />
<foo-2 />
<foo-3 />
<foo-4 />
...
<bar-1 />
<bar-2 />
<bar-3 />
<bar-4 />
...
<something-else-1 />
<something-else-2 />
</row>
</root>
I want to get all the "foo" nodes only, avoiding the use of loops if possible. I've been trying somenthing like:
xml.row.(new RegExp("foo[1-4]").test()))
and a few variations of the same line, but it does not seem to work. Is there any E4X syntax / method to get this done?? I've been googling for a while, and i've read the ECMAS documentation, but i can't get this done.
Thanks in advance!
해결책
xml.row.*.( /foo-[1-4]/.test(function::localName()) )
다른 팁
Btw, you can do it without regex too.
var foo = xml.row.*.(String(localName()).indexOf("foo-") == 0);
alert(foo.length() + "\n" + foo.toXMLString());
This is how you should be able to do it, but it doesn't work in Rhino:
xml.row.*.( /foo-[1-4]/.test(name()) ) // or localName()
For now, as far as I know, you will need to use a loop.
If you don't mind getting an array instead of an XMLList, and your version of Rhino supports array comprehensions, you could use this:
[foo for each (foo in xml.row.*) if (/foo-[1-4]/.test(foo.name()))]
It still uses a loop, but it's a little more declarative at least.
Edit: Like Elijah Grey mentioned in the comments, if you are using namespaces you would need to either call localName()
or name().localName
. Of course, to be completely correct, you would need to compare the namespace URI as well.
Also, apparently, SpiderMonkey (Firefox) requires you to prefix function calls with function::
in filter predicates, so the filter would look like this:
/foo-[1-4]/.test(function::name()) // or function::localName()
Typically, Rhino follows what SpiderMonkey does, so when it supports function calls in predicates, you may need the function::
prefix.