Orchestrator Class Library: XPath Query Builder

by Simon Sparks · 13 February 2026

To use this function add it to the class library file named Utilities.ts

GitHub Repository: https://github.com/SimonSparksUK/Orchestrator

Filename: Utilities.ts

Description: Orchestrator Class to Build an XPath Query

Sample Usage: Simple Filtering by Parent vCenter

let objXPathQuery: XPathQuery = new XPathQuery(XPathLogicalOperator.AND);
objXPathQuery.addXPathExpression(XPathFunction.NONE, XPathOperator.EQUAL, "sdkConnection/id", objVcSdkConnection.id, false);

let strXPathQuery: string = objXPathQuery.buildXPathQuery();
TypeScript

Sample Usage: ComplexFiltering by Parent vCenter

let objXPathQuery: XPathQuery = new XPathQuery(XPathLogicalOperator.AND);
objXPathQuery.addXPathExpression(XPathFunction.NONE, XPathOperator.EQUAL, "sdkConnection/id", objVcSdkConnection.id, false);
objXPathQuery.addXPathExpression(XPathFunction.STARTS_WITH, XPathOperator.EQUAL, "name", "dev", false);

let strXPathQuery: string = objXPathQuery.buildXPathQuery();
TypeScript

Class: XPathQuery

export class XPathQuery {
  private arrXPathExpression: XPathExpression[];
  private enumXPathLogicalOperator: XPathLogicalOperator;

  public constructor(enumXPathLogicalOperator: XPathLogicalOperator, arrXPathExpression?: XPathExpression[]) {
    if (arrXPathExpression) {
      this.arrXPathExpression = arrXPathExpression;
    }

    if (enumXPathLogicalOperator) {
      this.enumXPathLogicalOperator = enumXPathLogicalOperator;
    }
  }
}
TypeScript

Public Functions: Getters and Setters

public getXPathLogicalOperator(): XPathLogicalOperator {
  return this.enumXPathLogicalOperator;
}

public setXPathLogicalOperator(enumXPathLogicalOperator: XPathLogicalOperator): void {
  this.enumXPathLogicalOperator = enumXPathLogicalOperator;
}

public getXPathExpressions(): XPathExpression[] {
  return this.arrXPathExpression;
}

public setXPathExpressions(arrXPathExpression: XPathExpression[]): void {
  this.arrXPathExpression = arrXPathExpression;
}
TypeScript

Private Function: buildXPathExpression

private buildXPathExpression(objXPathExpression: XPathExpression): string {

  let strXPathFunction: string = objXPathExpression.enumXPathFunction;
  strXPathFunction = strXPathFunction.replace(XPathReplacement.FIELD, objXPathExpression.strFieldName);
  strXPathFunction = strXPathFunction.replace(XPathReplacement.FIND, objXPathExpression.strValue);

  if (objXPathExpression.intStartPosition) {
    strXPathFunction = strXPathFunction.replace(XPathReplacement.START_POSITION, objXPathExpression.intStartPosition.toString());
  }

  if (objXPathExpression.intLength) {
    strXPathFunction = strXPathFunction.replace(XPathReplacement.LENGTH, objXPathExpression.intLength.toString());
  }

  let strXPathExpression: string = `${strXPathFunction} `;

  if (objXPathExpression.enumXPathFunction === XPathFunction.CONTAINS || XPathFunction.MATCHES || XPathFunction.STARTS_WITH) {

    // No Additional Query Parts Required as They Compare to Boolean TRUE

  } else if (objXPathExpression.enumXPathFunction === XPathFunction.TRANSLATE_LOWER_TO_UPPER) {
    strXPathFunction = strXPathFunction + `${objXPathExpression.strValue.toUpperCase()}`;
  } else if (objXPathExpression.enumXPathFunction === XPathFunction.TRANSLATE_UPPER_TO_LOWER) {
    strXPathFunction = strXPathFunction + `${objXPathExpression.enumXPathOperator} ${objXPathExpression.strValue.toLowerCase()}`;
  } else {
    strXPathFunction = strXPathFunction + `${objXPathExpression.enumXPathOperator} ${objXPathExpression.enumXPathOperator} ${objXPathExpression.strValue}`;
  }

  if (objXPathExpression.blnNegateExpression === true) {
    strXPathExpression = `not(${strXPathExpression})`;
  }

  return strXPathExpression;
}
TypeScript

Public Function: addXPathExpression

public addXPathExpression(enumXPathFunction: XPathFunction, enumXPathOperator: XPathOperator, strFieldName: string, strValue: string, blnNegateExpression: boolean = false, intStartPosition?: number, intLength?: number): boolean {

  try {
    let objXPathExpression: XPathExpression = {
      enumXPathFunction: enumXPathFunction,
      enumXPathOperator: enumXPathOperator,
      strFieldName: strFieldName,
      strValue: strValue,
      blnNegateExpression: blnNegateExpression
    };

    if (intStartPosition) {
      objXPathExpression.intStartPosition = intStartPosition;
    }

    if (intLength) {
      objXPathExpression.intLength = intLength;
    }

    this.arrXPathExpression.push(objXPathExpression);

    return true;
  } catch (objException) {
    return false;
  }
}
TypeScript

Public Function: buildXPathQuery

public buildXPathQuery(): string {

  let strXPathQuery: string = ``;

  this.arrXPathExpression.forEach((objXPathExpression: XPathExpression, intIndex: number): void => {

    let strXPathExpression: string = this.buildXPathExpression(objXPathExpression);

    if (this.arrXPathExpression.length !== intIndex) {
      strXPathQuery = strXPathQuery + ` ${this.enumXPathLogicalOperator.toString()} ${strXPathExpression}`;
    }
  });

  return strXPathQuery;
}
TypeScript

Interface: XPathExpression

export interface XPathExpression {
  enumXPathFunction: XPathFunction;
  enumXPathOperator: XPathOperator;
  strFieldName: string;
  strValue: string;
  blnNegateExpression: boolean;
  intStartPosition?: number;
  intLength?: number;
}
TypeScript

Enumeration: XPathLogicalOperator

export enum XPathLogicalOperator {
  AND = "and",
  OR = "or"
}
TypeScript

Enumeration: XPathOperator

export enum XPathOperator {
  EQUAL = "=",
  NOT_EQUAL = "!=",
  LESS_THAN = "<",
  GREATER_THAN = ">",
  LESS_THAN_OR_EQUAL = "<=",
  GREATER_THAN_OR_EQUAL = ">="
}

Enumeration: XPath

export enum XPathReplacement {
  FIELD = "FIELD",
  FIND = "FIND",
  LENGTH = "LENGTH",
  START_POSITION = "START_POSITION"
}
TypeScript

Enumeration: XPathTranslate

export enum XPathTranslate {
  ALPHABET_LOWERCASE = "abcdefghijklmnopqrstuvwxyz",
  ALPHABET_UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
}
TypeScript

Enumeration: XPathFunction

export enum XPathFunction {
  NONE = `${XPathReplacement.FIELD}`,
  LAST = "last()",
  NODE = "node()",
  POSITION = "position()",
  STRING_LENGTH = `string-length(${XPathReplacement.FIELD})`,
  MATCHES = `matches(${XPathReplacement.FIELD}, ${XPathReplacement.FIND}) = true`,
  CONTAINS = `contains(${XPathReplacement.FIELD}, ${XPathReplacement.FIND}) = true`,
  STARTS_WITH = `starts-with(${XPathReplacement.FIELD}, ${XPathReplacement.FIND}) = true`,
  SUBSTRING_TO_END = `substring(${XPathReplacement.FIELD}, ${XPathReplacement.START_POSITION})`,
  SUBSTRING_TO_LENGTH = `substring(${XPathReplacement.FIELD}, ${XPathReplacement.START_POSITION}, ${XPathReplacement.LENGTH})`,
  TRANSLATE_LOWER_TO_UPPER = `translate(${XPathReplacement.FIELD}, ${XPathTranslate.ALPHABET_LOWERCASE}, ${XPathTranslate.ALPHABET_UPPERCASE})`,
  TRANSLATE_UPPER_TO_LOWER = `translate(${XPathReplacement.FIELD}, ${XPathTranslate.ALPHABET_UPPERCASE}, ${XPathTranslate.ALPHABET_LOWERCASE})`
}
TypeScript

Discover more from Cloud Build Tools

Subscribe to get the latest posts sent to your email.