handle scalar values

This commit is contained in:
Maciej Zawiasa 2016-11-25 21:34:31 +01:00
parent 62234629e2
commit 1112f56801
2 changed files with 53 additions and 16 deletions

View File

@ -2,7 +2,7 @@
import * as vsc from 'vscode'; import * as vsc from 'vscode';
import * as ext from '../Extension'; import * as ext from '../Extension';
import { XPathEvaluator } from '../services/XPathEvaluator'; import { XPathEvaluator, EvaluatorResult, EvaluatorResultType } from '../services/XPathEvaluator';
const CFG_SECTION: string = 'xmlTools'; const CFG_SECTION: string = 'xmlTools';
const CFG_PERSIST_QUERY: string = 'persistXPathQuery'; const CFG_PERSIST_QUERY: string = 'persistXPathQuery';
@ -59,12 +59,11 @@ export class XPathFeatureProvider {
// run the query // run the query
let xml: string = editor.document.getText(); let xml: string = editor.document.getText();
let nodes: Node[]; let evalResult: EvaluatorResult;
try { try {
nodes = XPathEvaluator.evaluate(query, xml, ignoreDefaultNamespace); evalResult = XPathEvaluator.evaluate(query, xml, ignoreDefaultNamespace);
} }
catch (error) { catch (error) {
console.error(error); console.error(error);
vsc.window.showErrorMessage(`Something went wrong while evaluating the XPath: ${error}`); vsc.window.showErrorMessage(`Something went wrong while evaluating the XPath: ${error}`);
@ -78,10 +77,13 @@ export class XPathFeatureProvider {
outputChannel.appendLine(`XPath Query: ${query}`); outputChannel.appendLine(`XPath Query: ${query}`);
outputChannel.append('\n'); outputChannel.append('\n');
nodes.forEach((node: XmlNode) => { if (evalResult.type === EvaluatorResultType.NODE_COLLECTION) {
(evalResult.result as Node[]).forEach((node: XmlNode) => {
outputChannel.appendLine(`[Line ${node.lineNumber}] ${node.localName}: ${node.textContent}`); outputChannel.appendLine(`[Line ${node.lineNumber}] ${node.localName}: ${node.textContent}`);
}); });
} else {
outputChannel.appendLine(`[Result]: ${evalResult.result}`);
}
outputChannel.show(vsc.ViewColumn.Three); outputChannel.show(vsc.ViewColumn.Three);
// if persistence is enabled, save the query for later // if persistence is enabled, save the query for later

View File

@ -4,8 +4,18 @@ import * as xpath from 'xpath';
let DOMParser = require('xmldom').DOMParser; let DOMParser = require('xmldom').DOMParser;
export class EvaluatorResult {
type: EvaluatorResultType;
result: Node[]|number|string|boolean;
}
export class EvaluatorResultType {
static SCALAR_TYPE: number = 0;
static NODE_COLLECTION: number = 1;
}
export class XPathEvaluator { export class XPathEvaluator {
static evaluate(query: string, xml: string, ignoreDefaultNamespace: boolean): Node[] { static evaluate(query: string, xml: string, ignoreDefaultNamespace: boolean): EvaluatorResult {
if (ignoreDefaultNamespace) { if (ignoreDefaultNamespace) {
xml = xml.replace(/xmlns=".+"/g, (match: string) => { xml = xml.replace(/xmlns=".+"/g, (match: string) => {
return match.replace(/xmlns/g, 'xmlns:default'); return match.replace(/xmlns/g, 'xmlns:default');
@ -17,14 +27,39 @@ export class XPathEvaluator {
let xdoc: Document = new DOMParser().parseFromString(xml, 'text/xml'); let xdoc: Document = new DOMParser().parseFromString(xml, 'text/xml');
let resolver: xpath.XPathNSResolver = xpath.createNSResolver(xdoc); let resolver: xpath.XPathNSResolver = xpath.createNSResolver(xdoc);
let expression: xpath.XPathExpression = xpath.createExpression(query, resolver); let result: xpath.XPathResult = xpath.evaluate(
let result: xpath.XPathResult = expression.evaluate(xdoc, xpath.XPathResult.ORDERED_NODE_ITERATOR_TYPE); query, // xpathExpression
xdoc, // contextNode
resolver, // namespaceResolver
xpath.XPathResult.ANY_TYPE, // resultType
null // result
)
let evalResult = new EvaluatorResult();
evalResult.type = EvaluatorResultType.SCALAR_TYPE;
switch(result.resultType) {
case xpath.XPathResult.NUMBER_TYPE:
evalResult.result = result.numberValue;
break;
case xpath.XPathResult.STRING_TYPE:
evalResult.result = result.stringValue;
break;
case xpath.XPathResult.BOOLEAN_TYPE:
evalResult.result = result.booleanValue;
break;
case xpath.XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
case xpath.XPathResult.ORDERED_NODE_ITERATOR_TYPE:
evalResult.result = result.booleanValue;
let node: Node; let node: Node;
while (node = result.iterateNext()) { while (node = result.iterateNext()) {
nodes.push(node); nodes.push(node);
} }
evalResult.result = nodes;
evalResult.type = EvaluatorResultType.NODE_COLLECTION;
break;
}
return nodes; return evalResult;
} }
} }