%%%COMMENTS:
%The function writes a XML file.
%INPUT arguments:
%1)XMLfilename: Filename or full pathname where the XML file is stored.
%(NOTE: the 2nd line of the XML file must be the DOC TYPE declaration)
%OUTPUT arguments:
%1)metadata: struct with metadata info.
%2)phys: struct with phys info.
%3)netState: struct with netState info.
function [metadata, phys, netState] = io_readXML(XMLfilename)
import org.apache.xerces.jaxp.*;
import org.xml.sax.*;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
% javaclasspath
% import
%1. -------- INITIALIZATION --------------
metadata = struct('title', [''], 'author', [''], 'date', [''], 'multihourPlanning', [''], 'planningAlgorithmFile', [''], 'planningAlgorithmParametersString', [''], ....
'flowGeneratorFile', [''], 'flowGeneratorParametersString', [''], 'trafficMatrixFile', [''], 'description', ['']);
phys = struct('N',[], 'M', [], 'nodeName', [], 'nodesPlaceMatrix',[],'nodePopulation',[], 'nodeTimezone', [],...
'nodeLevel',[], 'numberTxPerNode',[],'numberRxPerNode',[],'numberTWCPerNode',[],...
'linkTable',[], 'linkLengthInKm',[], 'numberWavelengthPerFiber',[],'levelMatrix',[],...
'lightpathCapacity',[],'incomingLinksToNode',[],'outgoingLinksFromNode',[],...
'distancesMatrix', []);
netState = struct('lightpathTable', [], 'lightpathRoutingMatrix', [] , 'flowRoutingMatrix', [] , 'flowTable', [],...
'numberOfOccupiedTxs' , [],'numberOfOccupiedRxs' , [], 'numberOfOccupiedTWCs' , []);
% 2. -------- XML VALIDATION & READING --------------
dbfactory = DocumentBuilderFactoryImpl();
dbfactory.setValidating(true);
%Create a parser (a document builder) from the document builder factory
parser = dbfactory.newDocumentBuilder();
valid = parser.isValidating();
% eh = DefaultHandler();
% parser.setErrorHandler(eh);
% We parse, read and validate the XML file at the same time.
%It's returned a Document Object Model
DOMnode = parser.parse(XMLfilename);
%DOMnode = xmlread(XMLfilename);
try
%3 --------- METADATA READING ------------------------
% We Create the Document Object Model and we setup the root node 'network'
docRootNode = DOMnode.getDocumentElement;
%We put the metadata (from the DOM) automatically into the metadata struct.
attributes_NodeMap = docRootNode.getAttributes();
for attributeIndex = 0:(attributes_NodeMap.getLength()-1),
fieldNameAsString = (attributes_NodeMap.item(attributeIndex).getNodeName().toCharArray())';
fieldValue = (attributes_NodeMap.item(attributeIndex).getNodeValue().toCharArray())';
metadata.(fieldNameAsString) = fieldValue;
end
% metadata.title = (docRootNode.getAttribute('title').toCharArray())';
% metadata.author = (docRootNode.getAttribute('author').toCharArray())';
% metadata.date = (docRootNode.getAttribute('date').toCharArray())';
% metadata.multihourPlanning = (docRootNode.getAttribute('multihourPlanning').toCharArray())';
% metadata.planningAlgorithmFile = (docRootNode.getAttribute('planningAlgorithmFile').toCharArray())';
% metadata.planningAlgorithmParametersString = (docRootNode.getAttribute('planningAlgorithmParametersString').toCharArray())';
% metadata.flowGeneratorFile = (docRootNode.getAttribute('flowGeneratorFile').toCharArray())';
% metadata.flowGeneratorParametersString = (docRootNode.getAttribute('flowGeneratorParametersString').toCharArray())';
% metadata.trafficMatrixFile = (docRootNode.getAttribute('trafficMatrixFile').toCharArray())';
% metadata.description = (docRootNode.getAttribute('description').toCharArray())';
%3 --------- NETWORK LAYERS READING ------------------------
% We identify the layers defined in the XML file
layerElements_NodeList = docRootNode.getElementsByTagName('layer');
for layerElementIndex = 0:(layerElements_NodeList.getLength()-1),
thisLayerElement = layerElements_NodeList.item(layerElementIndex);
layerType = (thisLayerElement.getAttribute('id').toCharArray())';
switch(layerType),
%we process the trafficDemand layer
case 'trafficDemand',
flowElements_NodeList = thisLayerElement.getElementsByTagName('flow');
%we process each traffic flow
for flowElementIndex = 0 : flowElements_NodeList.getLength()-1,
thisFlowElement = flowElements_NodeList.item(flowElementIndex);
flowID = str2num((thisFlowElement.getAttribute('id').toCharArray())');
netState.flowRoutingMatrix(flowID, :) = zeros(1,size(netState.flowRoutingMatrix,2)); % to artificially create the row
%We put the flow atrributes automatically into
%netState.flowTable for this flow
attributes_NodeMap = thisFlowElement.getAttributes();
for attributeIndex = 0 : attributes_NodeMap.getLength()-1,
attributeNameAsString = (attributes_NodeMap.item(attributeIndex).getNodeName().toCharArray())';
attributeValue = str2num((attributes_NodeMap.item(attributeIndex).getNodeValue().toCharArray())');
netState.flowTable(flowID,5) = -1;
netState.flowTable(flowID,6) = -1;
netState.flowTable(flowID,7) = -1;
switch attributeNameAsString,
case 'serialNumber',
netState.flowTable(flowID,1) = attributeValue;
case 'origNodeId',
netState.flowTable(flowID,2) = attributeValue;
case 'destNodeId',
netState.flowTable(flowID,3) = attributeValue;
case 'flowAverageRateDemand',
netState.flowTable(flowID,4) = attributeValue;
case 'flowPriority',
netState.flowTable(flowID,5) = attributeValue;
case 'flowInitTime',
netState.flowTable(flowID,6) = attributeValue;
case 'flowDuration',
netState.flowTable(flowID,7) = attributeValue;
end
end
%We put the flow routing automatically into
%netState.flowRouting for this flow
routingElements_NodeList = thisFlowElement.getElementsByTagName('flowRouting');
routingElement = routingElements_NodeList.item(0);
lightpathElements_NodeList = routingElement.getElementsByTagName('lightpathInFlow');
%we process each lightpath in the flow
for lightpathElementIndex = 0 : lightpathElements_NodeList.getLength()-1,
thisLightpathElement = lightpathElements_NodeList.item(lightpathElementIndex);
lpID = str2num((thisLightpathElement.getAttribute('id').toCharArray())');
%We put the lightpath atrributes automatically into
%netState.flowRoutingMatrix for this lp
attributes_NodeMap = thisLightpathElement.getAttributes();
for attributeIndex = 0 : attributes_NodeMap.getLength()-1,
attributeNameAsString = (attributes_NodeMap.item(attributeIndex).getNodeName().toCharArray())';
attributeValue = str2num((attributes_NodeMap.item(attributeIndex).getNodeValue().toCharArray())');
switch attributeNameAsString,
case 'averageRate',
netState.flowRoutingMatrix(flowID, lpID) = attributeValue;
end
end
end
end
%process the virtualTopology layer
case 'virtualTopology',
lightpathElements_NodeList = thisLayerElement.getElementsByTagName('lightpath');
%we process each lightpath
for lightpathElementIndex = 0 : lightpathElements_NodeList.getLength()-1,
thisLightpathElement = lightpathElements_NodeList.item(lightpathElementIndex);
lightpathID = str2num((thisLightpathElement.getAttribute('id').toCharArray())');
%We put the lightpath atrributes automatically into
%netState.lightpathTable for this lightpath
attributes_NodeMap = thisLightpathElement.getAttributes();
for attributeIndex = 0 : attributes_NodeMap.getLength()-1,
attributeNameAsString = (attributes_NodeMap.item(attributeIndex).getNodeName().toCharArray())';
attributeValue = str2num((attributes_NodeMap.item(attributeIndex).getNodeValue().toCharArray())');
switch attributeNameAsString,
case 'serialNumber',
netState.lightpathTable(lightpathID,1) = attributeValue;
case 'origNodeId',
netState.lightpathTable(lightpathID,2) = attributeValue;
case 'destNodeId',
netState.lightpathTable(lightpathID,3) = attributeValue;
end
end
%We put the lightpath routing automatically into
%netState.lightpathRoutingMatrix for this lightpath
routingElements_NodeList = thisLightpathElement.getElementsByTagName('lightpathRouting');
routingElement = routingElements_NodeList.item(0);
fibreElements_NodeList = routingElement.getElementsByTagName('fibreInLightpath');
%we process each fibre used in the lightpath
for fibreElementIndex = 0 : fibreElements_NodeList.getLength()-1,
thisFibreElement = fibreElements_NodeList.item(fibreElementIndex);
fibreID = str2num((thisFibreElement.getAttribute('id').toCharArray())');
%We put the fibre atrributes automatically into
%netState.lightpathRoutingMatrix for this lp
attributes_NodeMap = thisFibreElement.getAttributes();
for attributeIndex = 0 : attributes_NodeMap.getLength()-1,
attributeNameAsString = (attributes_NodeMap.item(attributeIndex).getNodeName().toCharArray())';
attributeValue = str2num((attributes_NodeMap.item(attributeIndex).getNodeValue().toCharArray())');
switch attributeNameAsString,
case 'wavelengthId',
netState.lightpathRoutingMatrix(lightpathID, fibreID) = attributeValue;
end
end
end
end
%process the physicalTopology layer
case 'physicalTopology',
% NODES
nodeElements_NodeList = thisLayerElement.getElementsByTagName('node');
phys.N = nodeElements_NodeList.getLength();
%we process each NODE
for nodeElementIndex = 0 : phys.N-1,
thisNodeElement = nodeElements_NodeList.item(nodeElementIndex);
nodeID = str2num((thisNodeElement.getAttribute('id').toCharArray())');
%We put the node atrributes automatically into the field of
%the phys struct related to the nodes.
attributes_NodeMap = thisNodeElement.getAttributes();
for attributeIndex = 0 : attributes_NodeMap.getLength()-1,
attributeNameAsString = (attributes_NodeMap.item(attributeIndex).getNodeName().toCharArray())';
attributeValueAsString = (attributes_NodeMap.item(attributeIndex).getNodeValue().toCharArray())';
switch attributeNameAsString,
case 'nodeName',
phys.nodeName{nodeID} = attributeValueAsString;
case 'xCoord',
phys.nodesPlaceMatrix(nodeID,1) = str2num(attributeValueAsString);
case 'yCoord',
phys.nodesPlaceMatrix(nodeID,2) = str2num(attributeValueAsString);
case 'nodePopulation',
phys.nodePopulation(nodeID) = str2num(attributeValueAsString);
case 'nodeTimezone',
phys.nodeTimezone(nodeID) = str2num(attributeValueAsString);
case 'nodeLevel',
phys.nodeLevel(nodeID) = str2num(attributeValueAsString);
end
end
%We put the info about eo transmitters, oe receivers and
%wavelength converters into the field of
%the phys struct related to the nodes.
% - EO TRANSMITTERS
eoTransmitterElements_NodeList = thisNodeElement.getElementsByTagName('eoTransmitter');
eoTransmitterElement = eoTransmitterElements_NodeList.item(0);
%We put the eo transmitters atrributes automatically into the fields of
%the phys struct related to them.
attributes_NodeMap = eoTransmitterElement.getAttributes();
for attributeIndex = 0 : attributes_NodeMap.getLength()-1,
attributeNameAsString = (attributes_NodeMap.item(attributeIndex).getNodeName().toCharArray())';
attributeValue = str2num((attributes_NodeMap.item(attributeIndex).getNodeValue().toCharArray())');
switch attributeNameAsString,
case 'number',
phys.numberTxPerNode(nodeID) = attributeValue;
end
end
% - OE RECEIVERS
oeReceiverElements_NodeList = thisNodeElement.getElementsByTagName('oeReceiver');
oeReceiverElement = oeReceiverElements_NodeList.item(0);
%We put the eo transmitters atrributes automatically into the fields of
%the phys struct related to them.
attributes_NodeMap = oeReceiverElement.getAttributes();
for attributeIndex = 0 : attributes_NodeMap.getLength()-1,
attributeNameAsString = (attributes_NodeMap.item(attributeIndex).getNodeName().toCharArray())';
attributeValue = str2num((attributes_NodeMap.item(attributeIndex).getNodeValue().toCharArray())');
switch attributeNameAsString,
case 'number',
phys.numberRxPerNode(nodeID) = attributeValue;
end
end
% - WAVELENGTH CONVERTERS
wcElements_NodeList = thisNodeElement.getElementsByTagName('wc');
wcElement = wcElements_NodeList.item(0);
%We put the eo transmitters atrributes automatically into the fields of
%the phys struct related to them.
attributes_NodeMap = wcElement.getAttributes();
for attributeIndex = 0 : attributes_NodeMap.getLength()-1,
attributeNameAsString = (attributes_NodeMap.item(attributeIndex).getNodeName().toCharArray())';
attributeValue = str2num((attributes_NodeMap.item(attributeIndex).getNodeValue().toCharArray())');
switch attributeNameAsString,
case 'number',
phys.numberTWCPerNode(nodeID) = attributeValue;
end
end
end
% FIBRE LINKS
fibreElements_NodeList = thisLayerElement.getElementsByTagName('fibre');
phys.M = fibreElements_NodeList.getLength();
%we process each FIBRE LINK
for fibreElementIndex = 0 : phys.M-1,
thisFibreElement = fibreElements_NodeList.item(fibreElementIndex);
fibreID = str2num((thisFibreElement.getAttribute('id').toCharArray())');
%We put the fibre atrributes automatically into the field of
%the phys struct related to the fibres.
attributes_NodeMap = thisFibreElement.getAttributes();
for attributeIndex = 0 : attributes_NodeMap.getLength()-1,
attributeNameAsString = (attributes_NodeMap.item(attributeIndex).getNodeName().toCharArray())';
attributeValue = str2num((attributes_NodeMap.item(attributeIndex).getNodeValue().toCharArray())');
switch attributeNameAsString,
case 'origNodeId',
phys.linkTable(fibreID,1) = attributeValue;
case 'destNodeId',
phys.linkTable(fibreID,2) = attributeValue;
case 'linkLengthInKm',
phys.linkLengthInKm(fibreID) = attributeValue;
case 'numberWavelengths',
phys.numberWavelengthPerFiber(fibreID) = attributeValue;
end
end
end
% LEVEL INFORMATION MATRIX
levelInformationMatrixElements_NodeList = thisLayerElement.getElementsByTagName('levelInformationMatrix');
levelInformationMatrixElement = levelInformationMatrixElements_NodeList.item(0);
levelFactorsElements_NodeList = levelInformationMatrixElement.getElementsByTagName('factor');
nrOfNodeLevels = levelFactorsElements_NodeList.getLength();
%we process each FACTOR of the LEVEL INFORMATION MATRIX
for levelFactorElementIndex = 0 : nrOfNodeLevels -1,
thisFactorElement = levelFactorsElements_NodeList.item(levelFactorElementIndex);
idOrig = str2num((thisFactorElement.getAttribute('idOrig').toCharArray())');
idDest = str2num((thisFactorElement.getAttribute('idDest').toCharArray())');
value = str2num((thisFactorElement.getAttribute('value').toCharArray())');
if (ismember(idOrig , [1:nrOfNodeLevels]) & ismember(idDest , [1:nrOfNodeLevels])),
phys.levelMatrix(idOrig,idDest) = value;
end
end
% LIGHTPATH CAPACITY
lightpathCapacityMatrixElements_NodeList = thisLayerElement.getElementsByTagName('lightpathCapacity');
lightpathCapacityElement = lightpathCapacityMatrixElements_NodeList.item(0);
phys.lightpathCapacity = str2num((lightpathCapacityElement.getAttribute('value').toCharArray())');
end
end
%We have to check that lightpathRoutingMatrix has the correct number of
%columns (number of links).
numberOfEmptyColumns=phys.M-size(netState.lightpathRoutingMatrix,2);
if(numberOfEmptyColumns~=0)
netState.lightpathRoutingMatrix=[netState.lightpathRoutingMatrix zeros(size(netState.lightpathRoutingMatrix,1),numberOfEmptyColumns)];
end
%4 --------- COMPUTATION OF REDUNDANT INFO FOR PHYS AND NETSTATE ------------------------
%%%% calculate redundant information included in the phys structure
% 1.- Incoming Fibre Links to each node.
phys.incomingLinksToNode = cell (1,phys.N);
for node=1:phys.N
phys.incomingLinksToNode {node} = makeRowVector(find(phys.linkTable(:,2)==node));
end
% 2.- Outgoing Fibre Links from each node.
phys.outgoingLinksFromNode = cell (1,phys.N);
for node=1:phys.N
phys.outgoingLinksFromNode {node} = makeRowVector(find(phys.linkTable(:,1)==node));
end
% 3.- Euclidean distances (in Km) between the pairs of nodes
phys.distancesMatrix = calculateDistanceMatrix(phys.nodesPlaceMatrix);
% 4.- Distances in Km of the Physical Links
if isempty(phys.linkLengthInKm), %if there is no "linkLengthInKm" attribute in the XML file.
phys.linkLengthInKm = zeros (1,phys.M);
for m=1:phys.M,
phys.linkLengthInKm(m)=phys.distancesMatrix(phys.linkTable(m,1),phys.linkTable(m,2));
end
end
%%%% calculate redundant information included in the NETSTATE structure
%We estimate if netState is empty (and therefore, there is no netState extra info)
netStateIsEmpty = 0;
namesOfNetStateFields = fieldnames(netState);
for index = 1:4,%just the 4 first fields
if isempty(netState.(namesOfNetStateFields{index})), netStateIsEmpty = 1; break; end
end
if netStateIsEmpty == 0,
% 1 & 2.- Nr of Used EO TXs & Nr of Used OE RXs.
for nodei=1:phys.N
netState.numberOfOccupiedTxs(nodei) = length(find(netState.lightpathTable(:,2)==nodei));
netState.numberOfOccupiedRxs(nodei) = length(find(netState.lightpathTable(:,3)==nodei));
end
% 3.- Nr of Used TWCs.
numberOfLightpaths=size(netState.lightpathTable,1);
netState.numberOfOccupiedTWCs=zeros(phys.N,1);
for lpID=1:numberOfLightpaths,
[sequenceOfNodeIDs, sequenceOfFiberIDs, sequenceOfWavelengthIDs] = lightpathPathComputation (lpID, phys, netState);
for i=1:length(sequenceOfFiberIDs)-1,
if sequenceOfWavelengthIDs(i) ~= sequenceOfWavelengthIDs(i+1),
netState.numberOfOccupiedTWCs (sequenceOfNodeIDs(i+1)) = netState.numberOfOccupiedTWCs (sequenceOfNodeIDs(i+1)) + 1;
end
end
end
end
catch
[errormsg errorid]= lasterr;
error(['Error on reading XML file ->' errormsg])
end