| 732 | | |
| | 728 | function getElementsByXPath(xpath, node) { |
| | 729 | var nodesSnapshot = getXPathResult(xpath, node, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE); |
| | 730 | var data = []; |
| | 731 | for (var i = 0; i < nodesSnapshot.snapshotLength; i++) { |
| | 732 | data.push(nodesSnapshot.snapshotItem(i)); |
| | 733 | } |
| | 734 | return data; |
| | 735 | } |
| | 736 | function getFirstElementByXPath(xpath, node) { |
| | 737 | var result = getXPathResult(xpath, node, XPathResult.FIRST_ORDERED_NODE_TYPE); |
| | 738 | return result.singleNodeValue; |
| | 739 | } |
| | 740 | function getXPathResult(xpath, node, resultType) { |
| | 741 | var node = node || document; |
| | 742 | var doc = node.ownerDocument || node; |
| | 743 | var resolver = doc.createNSResolver(node.documentElement || node); |
| | 744 | // Use |node.lookupNamespaceURI('')| for Opera 9.5 |
| | 745 | var defaultNS = node.lookupNamespaceURI(window.opera ? '' : null); |
| | 746 | if (defaultNS) { |
| | 747 | var defaultPrefix = '__default__'; |
| | 748 | xpath = addDefaultPrefix(xpath, defaultPrefix); |
| | 749 | var defaultResolver = resolver; |
| | 750 | resolver = function (prefix) { |
| | 751 | return (prefix == defaultPrefix) ? defaultNS : defaultResolver.lookupNamespaceURI(prefix); |
| | 752 | } |
| | 753 | } |
| | 754 | return doc.evaluate(xpath, node, resolver, resultType, null); |
| | 755 | } |
| | 756 | function addDefaultPrefix(xpath, prefix) { |
| | 757 | var tokenPattern = /([A-Za-z_\u00c0-\ufffd][\w\-.\u00b7-\ufffd]*|\*)\s*(::?|\()?|(".*?"|'.*?'|\d+(?:\.\d*)?|\.(?:\.|\d+)?|[\)\]])|(\/\/?|!=|[<>]=?|[\(\[|,=+-])|([@$])/g; |
| | 758 | var TERM = 1, OPERATOR = 2, MODIFIER = 3; |
| | 759 | var tokenType = OPERATOR; |
| | 760 | prefix += ':'; |
| | 761 | function replacer(token, identifier, suffix, term, operator, modifier) { |
| | 762 | if (suffix) { |
| | 763 | tokenType = |
| | 764 | (suffix == ':' || (suffix == '::' && (identifier == 'attribute' || identifier == 'namespace'))) |
| | 765 | ? MODIFIER : OPERATOR; |
| | 766 | } else if (identifier) { |
| | 767 | if (tokenType == OPERATOR && identifier != '*') { |
| | 768 | token = prefix + token; |
| | 769 | } |
| | 770 | tokenType = (tokenType == TERM) ? OPERATOR : TERM; |
| | 771 | } else { |
| | 772 | tokenType = term ? TERM : operator ? OPERATOR : MODIFIER; |
| | 773 | } |
| | 774 | return token; |
| | 775 | } |
| | 776 | return xpath.replace(tokenPattern, replacer); |
| | 777 | } |