Add Get Current XPath

This commit also moves some shared code to a common class.

Issue: #85
This commit is contained in:
Josh Johnson 2018-05-29 21:38:11 -04:00
parent af2060dc38
commit 6a92fa96f2
10 changed files with 223 additions and 84 deletions

View file

@ -0,0 +1,21 @@
import { window } from "vscode";
import { TextEditor, TextEditorEdit } from "vscode";
import { DOMParser } from "xmldom";
import { XPathBuilder } from "../xpath-builder";
export function getCurrentXPath(editor: TextEditor, edit: TextEditorEdit): void {
if (!editor.selection) {
window.showInformationMessage("Please put your cursor in an element or attribute name.");
return;
}
const document = new DOMParser().parseFromString(editor.document.getText());
const xpath = new XPathBuilder(document).build(editor.selection.start);
window.showInputBox({
value: xpath,
valueSelection: undefined
});
}

View file

@ -1 +1,2 @@
export * from "./evaluateXPath";
export * from "./getCurrentXPath";

View file

@ -1 +1,2 @@
export * from "./xpath-builder";
export * from "./xpath-evaluator";

View file

@ -0,0 +1,41 @@
import { Position } from "vscode";
import { DOMParser } from "xmldom";
import { XmlTraverser } from "../common";
export class XPathBuilder {
private _xmlTraverser: XmlTraverser;
constructor(private _xmlDocument: Document) {
this._xmlTraverser = new XmlTraverser(this._xmlDocument);
}
build(position: Position): string {
const selectedNode = this._xmlTraverser.getNodeAtPosition(position);
return this._buildCore(selectedNode);
}
private _buildCore(selectedNode: Node): string {
if (selectedNode === this._xmlDocument.documentElement) {
return `/${selectedNode.nodeName}`;
}
if (!this._xmlTraverser.isElement(selectedNode)) {
return `${this._buildCore((selectedNode as any).ownerElement)}/@${selectedNode.nodeName}`;
}
else if (this._xmlTraverser.hasSimilarSiblings(selectedNode)) {
const siblings = this._xmlTraverser.getSiblings(selectedNode);
const xPathIndex = (siblings.indexOf(selectedNode) + 1);
return `${this._buildCore(selectedNode.parentNode)}/${selectedNode.nodeName}[${xPathIndex}]`;
}
else {
return `${this._buildCore(selectedNode.parentNode)}/${selectedNode.nodeName}`;
}
}
}