This is Interesting: Free Magazines for Graphics designers and webmasters  


Home > Archive > Mozilla XML > April 2005 > select nodes with xpath, having by specific attribute named 'class'





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author select nodes with xpath, having by specific attribute named 'class'
Marek Mänd

2005-04-04, 12:35 pm

<style>
.marek{}
</style>
etc..
<root>
<element class="marek mand"/>
<element class="mand marek"/>
<element class="mand marekmänd"/>
<element class="mand marekk"/>
</root>

I would like to know what is the XPath expression for Mozillas
JavaScript document.evaluate method first argument, if i want to get all
the nodes, that have the 'css'-class named "marek" set.

By above data only 2 elements should be returned, because they and they
only have the 'css' class "marek" set. The XPath expression should not
match 'marekk' nor 'marekmänd'.


I read few articles about xpath and i didnt saw any regular expressions
to be used there, but what i saw was that the xpath string functions are
definately too weak and clumsy to achieve my goal. I am new to XPath, so
i thought some master regular could teach me a bit.

TIA
Martin Honnen

2005-04-04, 12:35 pm



Marek Mänd wrote:

> <style>
> .marek{}
> </style>
> etc..
> <root>
> <element class="marek mand"/>
> <element class="mand marek"/>
> <element class="mand marekmänd"/>
> <element class="mand marekk"/>
> </root>
>
> I would like to know what is the XPath expression for Mozillas
> JavaScript document.evaluate method first argument, if i want to get all
> the nodes, that have the 'css'-class named "marek" set.
>
> By above data only 2 elements should be returned, because they and they
> only have the 'css' class "marek" set. The XPath expression should not
> match 'marekk' nor 'marekmänd'.


XPath 1.0 is not very strong in dealing with string values which are
really a list of separate values thus if you are using XPath within
JavaScript I think it is easier to start with XPath e.g.
//element[contains(@class, 'marek')]
and then look at the result and use a JavaScript regular expression on
the class attribute value to find those that match what you are looking for:

function findElementsByClassName (xmlDocument, className) {
var classNamePattern = new RegExp('(^|\\s+)' + className + '(\\s+|$)');
var xpathExpression = '//*[contains(@class, "' + className + '")]';
var elements = [];
var xpathResult = xmlDocument.evaluate(
xpathExpression,
xmlDocument,
null,
XPathResult.ORDERED_NODE_ITERATOR_TYPE,
null
);
var element;
while ((element = xpathResult.iterateNext())) {
classNamePattern.lastIndex = 0;
if (classNamePattern.test(element.getAttribute('class'))) {
elements.push(element);
}
}
return elements;
}

Using only XPath 1.0 it is very convoluted, watch out for line breaks
the posting introduces:

function findElementsByClassName (xmlDocument, className) {
var xpathExpression =
'//element[normalize-space(@class) = "' + className + '"' +
' or starts-with(normalize-space(@class), "' + className + ' ")' +
' or contains(normalize-space(@class), " ' + className + ' ")' +
' or (substring(normalize-space(@class),
string-length(normalize-space(@class)) ' +
' - string-length(" ' + className + '") + 1) = " ' + className + '")]';
var elements = [];
var xpathResult = xmlDocument.evaluate(
xpathExpression,
xmlDocument,
null,
XPathResult.ORDERED_NODE_ITERATOR_TYPE,
null
);
var element;
while ((element = xpathResult.iterateNext())) {
elements.push(element);
}
return elements;
}


--

Martin Honnen
http://JavaScript.FAQTs.com/
Marek Mänd

2005-04-04, 12:35 pm

Martin Honnen wrote:
> XPath 1.0 is not very strong in dealing with string values which are
> really a list of separate values thus if you are using XPath within
> JavaScript I think it is easier to start with XPath


Thank You for Your superb answer.
Being back for some months in JS-world, I want to learn something new
thatswhy i dropped that approach, but yes, it would be reasonable to do
so as it would give more flexibility over (e.c. select nodes that have
specific two/three etc 'separate-subvalues' set - which probably would
be definately PITA with Xpath ... ) 'pure' allsolving Xpath expression.


> Using only XPath 1.0 it is very convoluted, watch out for line breaks
> the posting introduces:
> function findElementsByClassName (xmlDocument, className) {
> var xpathExpression =
> '//element[normalize-space(@class) = "' + className + '"' +
> ' or starts-with(normalize-space(@class), "' + className + ' ")' +
> ' or contains(normalize-space(@class), " ' + className + ' ")' +
> ' or (substring(normalize-space(@class),
> string-length(normalize-space(@class)) ' +
> ' - string-length(" ' + className + '") + 1) = " ' + className + '")]';
> var elements = [];


Indeed it looks quite awkward. I'd wish there were possibilities to
write regexes in the path, but sadly by the specification things arent
meant to be done so.

I have a small refining question:

why do I have to use
normalize-space(@class) = "className"
too?
Why isnt the
starts-with(normalize-space(@class), "className")
sufficient for both cases?


TIA.


Marek Mänd

2005-04-04, 12:35 pm

Marek Mänd wrote:
> I have a small refining question:
> why do I have to use
> normalize-space(@class) = "className"
> too?
> Why isnt the
> starts-with(normalize-space(@class), "className")
> sufficient for both cases?


END OF THREAD.

i understood now looking more carefully why,
just was yesterday very tired and too eager to ask.

Thanks for the answer, i will put heavy use on that code.
Sponsored Links


Copyright 2003 - 2008 forum4designers.com  Software forum  Computer Hardware reviews