Consider a text containing both single and double quotes. I am storing it in a JS literal string
const sampleText = `Uses the "crow's foot" notation rather than classic ER notation to depict a relationship`
I need to find the div element which contains this text. I am using document.evaluate function
const xpath = `//div[text()="${sampleText}"]`
document
.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null)
.iterateNext();
But the function call throws not a valid XPath.
Tried adding escaped blackslash
\\
before double quotes
"
in sampleText
but no luck.
Failed attempt:
const sampleText = `Uses the \\"crow's foot\\" notation rather than classic ER notation to depict a relationship`
Error:
Failed to execute 'evaluate' on 'Document': The string '//div/text()="Uses the \"crow's foot\" notation rather than classic ER notation to depict a relationship"' is not a valid XPath expression.
Also other answers couldn't help as my string contains both double and single quotes and need code in JS
Found a solution. Use the concat
function and separate the quotes. Wrote a simple function to take a string and out a literal string to be used in concat(outString)
const xConcatString = (sampleText) => {
const splitText = sampleText.split('"');
const xText = [];
splitText.forEach((ele) => {
xText.push(`"${ele}"`);
xText.push(`'"'`);
});
xText.pop();
return xText.join(",");
};
Explanation:
xpath doesn't support escaping characters , thus the only option is to use double quotes
when string contains single quotes
and vice versa.
But we can use the concat
operator to split the string by any 1 type of quote you decide and wrap it in another. In above function I am splitting by single quote
.
Also .
works better than text()
when finding xpath element via text inside it.
Thus from sample in the question,
const sampleText = `Uses the "crow's foot" notation rather than classic ER notation to depict a relationship`
const xpath = `//div[.=concat(${xConcatString(sampleText)})]`
document
.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null)
.iterateNext();
Tip: The quotes on output string from xConcatString
will get confusing but its a comma separated list of string and each string element is enclosed in double quotes