com.gargoylesoftware.htmlunit.javascript.host.dom.XPathResult Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xlt Show documentation
Show all versions of xlt Show documentation
XLT (Xceptance LoadTest) is an extensive load and performance test tool developed and maintained by Xceptance.
/*
* Copyright (c) 2002-2021 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF78;
import java.util.List;
import com.gargoylesoftware.htmlunit.html.DomAttr;
import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstant;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
import net.sourceforge.htmlunit.corejs.javascript.Context;
/**
* A JavaScript object for {@code XPathResult}.
*
* @author Ahmed Ashour
* @author Chuck Dumont
* @author Ronald Brill
*/
@JsxClass({CHROME, EDGE, FF, FF78})
public class XPathResult extends SimpleScriptable {
/**
* This code does not represent a specific type.
* An evaluation of an XPath expression will never produce this type. If this type is requested,
* then the evaluation returns whatever type naturally results from evaluation of the expression.
*/
@JsxConstant
public static final int ANY_TYPE = 0;
/**
* The result is a number.
*/
@JsxConstant
public static final int NUMBER_TYPE = 1;
/**
* The result is a string.
*/
@JsxConstant
public static final int STRING_TYPE = 2;
/**
* The result is a boolean.
*/
@JsxConstant
public static final int BOOLEAN_TYPE = 3;
/**
* The result is a node set that will be accessed iteratively, which may not produce nodes in a particular order.
* This is the default type returned if the result is a node set and {@link #ANY_TYPE} is requested.
*/
@JsxConstant
public static final int UNORDERED_NODE_ITERATOR_TYPE = 4;
/**
* The result is a node set that will be accessed iteratively, which will produce document-ordered nodes.
*/
@JsxConstant
public static final int ORDERED_NODE_ITERATOR_TYPE = 5;
/**
* The result is a node set that will be accessed as a snapshot list of nodes
* that may not be in a particular order.
*/
@JsxConstant
public static final int UNORDERED_NODE_SNAPSHOT_TYPE = 6;
/**
* The result is a node set that will be accessed as a snapshot list of nodes
* that will be in original document order.
*/
@JsxConstant
public static final int ORDERED_NODE_SNAPSHOT_TYPE = 7;
/**
* The result is a node set and will be accessed as a single node, which may be null if the node set is empty.
* If there is more than one node in the actual result,
* the single node returned might not be the first in document order.
*/
@JsxConstant
public static final int ANY_UNORDERED_NODE_TYPE = 8;
/**
* The result is a node set and will be accessed as a single node, which may be null if the node set is empty.
* If there are more than one node in the actual result,
* the single node returned will be the first in document order.
*/
@JsxConstant
public static final int FIRST_ORDERED_NODE_TYPE = 9;
private List result_;
private int resultType_;
/**
* The index of the next result.
*/
private int iteratorIndex_;
/**
* Creates an instance.
*/
@JsxConstructor
public XPathResult() {
}
/**
* @param result the evaluation result
* @param type If a specific type is specified, then the result will be returned as the corresponding type
*/
void init(final List result, final int type) {
result_ = result;
resultType_ = -1;
if (result_.size() == 1) {
final Object o = result_.get(0);
if (o instanceof Number) {
resultType_ = NUMBER_TYPE;
}
else if (o instanceof String) {
resultType_ = STRING_TYPE;
}
else if (o instanceof Boolean) {
resultType_ = BOOLEAN_TYPE;
}
}
if (resultType_ == -1) {
if (type != ANY_TYPE) {
resultType_ = type;
}
else {
resultType_ = UNORDERED_NODE_ITERATOR_TYPE;
}
}
iteratorIndex_ = 0;
}
/**
* The code representing the type of this result, as defined by the type constants.
* @return the code representing the type of this result
*/
@JsxGetter
public int getResultType() {
return resultType_;
}
/**
* The number of nodes in the result snapshot.
* @return the number of nodes in the result snapshot
*/
@JsxGetter
public int getSnapshotLength() {
if (resultType_ != UNORDERED_NODE_SNAPSHOT_TYPE && resultType_ != ORDERED_NODE_SNAPSHOT_TYPE) {
throw Context.reportRuntimeError("Cannot get snapshotLength for type: " + resultType_);
}
return result_.size();
}
/**
* The value of this single node result, which may be null.
* @return the value of this single node result, which may be null
*/
@JsxGetter
public Node getSingleNodeValue() {
if (resultType_ != ANY_UNORDERED_NODE_TYPE && resultType_ != FIRST_ORDERED_NODE_TYPE) {
throw Context.reportRuntimeError("Cannot get singleNodeValue for type: " + resultType_);
}
if (!result_.isEmpty()) {
return (Node) ((DomNode) result_.get(0)).getScriptableObject();
}
return null;
}
/**
* Iterates and returns the next node from the node set or {@code null} if there are no more nodes.
* @return the next node
*/
@JsxFunction
public Node iterateNext() {
if (resultType_ != UNORDERED_NODE_ITERATOR_TYPE && resultType_ != ORDERED_NODE_ITERATOR_TYPE) {
throw Context.reportRuntimeError("Cannot get iterateNext for type: " + resultType_);
}
if (iteratorIndex_ < result_.size()) {
return (Node) ((DomNode) result_.get(iteratorIndex_++)).getScriptableObject();
}
return null;
}
/**
* Returns the indexth item in the snapshot collection.
* If index is greater than or equal to the number of nodes in the list, this method returns null.
* @param index Index into the snapshot collection
* @return the node at the indexth position in the NodeList, or null if that is not a valid index
*/
@JsxFunction
public Node snapshotItem(final int index) {
if (resultType_ != UNORDERED_NODE_SNAPSHOT_TYPE && resultType_ != ORDERED_NODE_SNAPSHOT_TYPE) {
throw Context.reportRuntimeError("Cannot get snapshotLength for type: " + resultType_);
}
if (index >= 0 && index < result_.size()) {
return (Node) ((DomNode) result_.get(index)).getScriptableObject();
}
return null;
}
/**
* Returns the value of this number result.
* @return the value of this number result
*/
@JsxGetter
public double getNumberValue() {
if (resultType_ != NUMBER_TYPE) {
throw Context.reportRuntimeError("Cannot get numberValue for type: " + resultType_);
}
final String asString = asString();
Double answer;
try {
answer = Double.parseDouble(asString);
}
catch (final NumberFormatException e) {
answer = Double.NaN;
}
return answer;
}
/**
* Returns the value of this boolean result.
* @return the value of this boolean result
*/
@JsxGetter
public boolean isBooleanValue() {
if (resultType_ != BOOLEAN_TYPE) {
throw Context.reportRuntimeError("Cannot get booleanValue for type: " + resultType_);
}
return !result_.isEmpty();
}
/**
* Returns the value of this string result.
* @return the value of this string result
*/
@JsxGetter
public String getStringValue() {
if (resultType_ != STRING_TYPE) {
throw Context.reportRuntimeError("Cannot get stringValue for type: " + resultType_);
}
return asString();
}
private String asString() {
final Object resultObj = result_.get(0);
if (resultObj instanceof DomAttr) {
return ((DomAttr) resultObj).getValue();
}
if (resultObj instanceof DomNode) {
return ((DomNode) resultObj).asText();
}
return resultObj.toString();
}
}