Re: select nodes with xpath, having by specific attribute named 'class' the 'subvalue part' set
Martin Honnen <[email protected]>
| Newsgroups | gmane.comp.mozilla.devel.xml |
|---|---|
| Organization | Liberty Development |
| Message-ID | <[email protected]> |
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/