import {XMLParser, type X2jOptions} from 'fast-xml-parser'; import { UAObject } from './UAObject'; import type { UABaseNode } from './UABaseNode'; import { UAVariable } from './UAVariable'; import { UAMethod } from './UAMethod'; import { NamespaceTable } from './NameSpaceTable'; import { Model } from './Model'; import { XMLElem, type IToXML } from '@/util/XmlElem'; import { UAReferenceType } from './UAReferenceType'; export class UANodeSet implements IToXML{ constructor(public fileName: string, public models: Model[], public nodes: UABaseNode[], public nameSpaceTable: NamespaceTable) { } reIndex(nst: NamespaceTable) { //add all missing namespaces to addressspace ns table for(const value of this.nameSpaceTable.nsMap.getValues()) { nst.addUri(value); } for(const node of this.nodes) { node.reIndex(nst, this.nameSpaceTable); } } resolveReferences(nm: Map) { for(const node of this.nodes) { node.resolveReferences(nm); } } toXML(lnst: NamespaceTable, gnst: NamespaceTable): XMLElem { const xmlUANodeSet =new XMLElem('UANodeSet'); const xmlNameSpaceUris=xmlUANodeSet.add(new XMLElem('NamespaceUris')); for(let i=0;i { const xml= await (await fetch(url)).text(); const fileName= url.split('/').pop()||url return this.parse(xml, fileName); } static async parse(xml: string, fileName: string): Promise { const parseOptions:Partial={ ignoreAttributes: false, alwaysCreateTextNode: true, //force consistent result parseTagValue:false, //disable number detection. Otherwise string values might end up as numbers. // eslint-disable-next-line @typescript-eslint/no-unused-vars isArray: (name, jpath, isLeafNode, isAttribute):boolean => { switch(jpath) { case 'UANodeSet.NamespaceUris.Uri': case 'UANodeSet.Models.Model': case 'UANodeSet.UAObject': case 'UANodeSet.UAObject.References.Reference': case 'UANodeSet.UAMethod': case 'UANodeSet.UAMethod.References.Reference': case 'UANodeSet.UAVariable': case 'UANodeSet.UAVariable.References.Reference': case 'UANodeSet.UAReferenceType': case 'UANodeSet.UAReferenceType.References.Reference': return true; default: return false; } } } const parser = new XMLParser(parseOptions); const xmlObj = parser.parse(xml); const models: Model[]=[]; const xmlModels=xmlObj['UANodeSet']['Models']||[]; for(const xmlModel of xmlModels.Model) { models.push(Model.fromXML(xmlModel)); } const nodes:UABaseNode[]=[]; const xmlObjects=xmlObj['UANodeSet']['UAObject']||[]; for(const xmlObject of xmlObjects) { nodes.push(UAObject.fromXML(xmlObject)); } const xmlVariables=xmlObj['UANodeSet']['UAVariable']||[]; for(const xmlVariable of xmlVariables) { nodes.push(UAVariable.fromXML(xmlVariable)); } const xmlMethods=xmlObj['UANodeSet']['UAMethod']||[]; for(const xmlMethod of xmlMethods) { nodes.push(UAMethod.fromXML(xmlMethod)); } const xmlReferenceTypes=xmlObj['UANodeSet']['UAReferenceType']||[]; for(const xmlReferenceType of xmlReferenceTypes) { nodes.push(UAReferenceType.fromXML(xmlReferenceType)); } const uaNamespaceUris=xmlObj['UANodeSet']['NamespaceUris']||[]; const nst=new NamespaceTable(); for(const nsUri of uaNamespaceUris['Uri']||[]) { nst.addUri(nsUri['#text']) } return new UANodeSet(fileName, models, nodes, nst); } }