Files
appium/packages/universal-xml-plugin/lib/xpath.js
renovate[bot] 3d674d0085 fix(universal-xml-plugin): update dependency @xmldom/xmldom to v0.9.2 (#20537)
* fix(universal-xml-plugin): update dependency @xmldom/xmldom to v0.9.2

* wrap different type for now

* revert some redundant lines, add annotation

* Add a url to the xmldom ticket as a reference

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Kazuaki Matsuo <fly.49.89.over@gmail.com>
2024-09-09 15:03:34 +02:00

61 lines
1.7 KiB
JavaScript

import {select as xpathQuery} from 'xpath';
import {DOMParser, MIME_TYPE} from '@xmldom/xmldom';
import _ from 'lodash';
export function runQuery(query, xmlStr) {
const dom = new DOMParser().parseFromString(xmlStr, MIME_TYPE.XML_TEXT);
// @ts-expect-error Misssing Node properties are not needed.
// https://github.com/xmldom/xmldom/issues/724
const nodes = xpathQuery(query, dom);
return nodes;
}
/**
*
* @param {string} query
* @param {string} xmlStr
* @param {boolean} multiple
* @returns {string|null}
*/
export function transformQuery(query, xmlStr, multiple) {
const nodes = runQuery(query, xmlStr);
if (!_.isArray(nodes)) {
return null;
}
const newQueries = nodes.map((node) => {
const indexPath = getNodeAttrVal(node, 'indexPath');
// at this point indexPath will look like /0/0/1/1/0/1/0/2
let newQuery = indexPath
.substring(1) // remove leading / so we can split
.split('/') // split into idnexes
.map((indexStr) => {
// map to xpath node indexes (1-based)
const xpathIndex = parseInt(indexStr, 10) + 1;
return `*[${xpathIndex}]`;
})
.join('/'); // reapply /
// now to make this a valid xpath from the root, prepend the / we removed earlier
return `/${newQuery}`;
});
let newSelector = null;
if (newQueries.length) {
if (multiple) {
newSelector = newQueries.join(' | ');
} else {
newSelector = newQueries[0];
}
}
return newSelector;
}
export function getNodeAttrVal(node, attr) {
const attrObjs = Object.values(node.attributes).filter((obj) => obj.name === attr);
if (!attrObjs.length) {
throw new Error(`Tried to retrieve a node attribute '${attr}' but the node didn't have it`);
}
return attrObjs[0].value;
}