/* * Création de la liste de tous les nœuds de l'arbre * */ protected void getNodesList(ContainsNode startNode, List <ContainsNode> lstNodes) { foreach (ContainsNode curNode in startNode.childrens) { lstNodes.Add(curNode); getNodesList(curNode, lstNodes); } }
public SedaSummaryRngGenerator() : base() { // rootContainsNode est marqué avec l'ID "root" rootContainsNode = new ContainsNode("root", null, true); currentContainsNode = rootContainsNode; currentPass = 1; }
public void C10_rootContainsTest() { ContainsNode root = new ContainsNode("root", null, true); Assert.AreNotEqual(null, root); Assert.AreEqual(0, root.getNbDocuments()); Assert.AreEqual(null, root.next()); Assert.AreEqual("root", root.getName()); Assert.AreEqual(null, root.getParent()); }
private String tabs; // pour l'indentation des traces #endregion Fields #region Constructors /* * Le premier nœud doit être créé avec un parentNode null * */ public ContainsNode(String nodeId, ContainsNode parentNode, bool bContainsIsMandatory) { objectIdentifier = nodeId; nbDocuments = 0; childrens = new List<ContainsNode>(); parent = parentNode; if (parentNode == null) { tabs = "\t"; } else { tabs = parentNode.tabs + "\t"; } mandatory = bContainsIsMandatory; }
/* * Le premier nœud doit être créé avec un parentNode null * */ public ContainsNode(String nodeId, ContainsNode parentNode, bool bContainsIsMandatory) { objectIdentifier = nodeId; nbDocuments = 0; childrens = new List <ContainsNode>(); parent = parentNode; if (parentNode == null) { tabs = "\t"; } else { tabs = parentNode.tabs + "\t"; } mandatory = bContainsIsMandatory; }
/* * Permet de récupérer le chemin relatif du nœud courant * retourne le nom du tag précédé des tags numérotés de ses ancètres * les tags non numérotés sont exclus de cette liste * exemple : * /TAG_A[#1]/TAG_B/TAG_C[#2]/TAG_D/THIS_TAG * a pour chemin relatif * TAG_A[#1]//TAG_C[#2]//THIS_TAG * * TODO: à optimiser, attribut chemin relatif, calcul des chemins * relatifs déclenché par exemple à computeNbDocuments * */ public String getRelativeContext() { String context = String.Empty; ContainsNode node = this; while ((node = node.getParent()) != null) { String parentName = node.getName(); Regex r = new Regex(@"\[#(\d+)\]"); MatchCollection matches = r.Matches(parentName); if (matches.Count != 0) { context = parentName + "//" + context; } } context += this.getName(); return(context); }
public void C11_rootChildrensContainsTest() { ContainsNode root = new ContainsNode("root", null, true); ContainsNode child1 = new ContainsNode("child1", root, true); ContainsNode child11 = new ContainsNode("child11", child1, true); ContainsNode child2 = new ContainsNode("child2", root, true); ContainsNode child21 = new ContainsNode("child21", child2, true); ContainsNode child22 = new ContainsNode("child22", child2, true); Assert.AreEqual("child11", child11.getName(), "child11.getDocumentName()"); Assert.AreEqual("child1", child11.getParent().getName(), "child11.getParent()"); Assert.AreEqual("child22", child22.getName(), "child22.getDocumentName()"); Assert.AreEqual("child2", child22.getParent().getName(), "child22.getParent()"); Assert.AreEqual("child2", child2.getName(), "child2.getDocumentName()"); Assert.AreEqual("root", child2.getParent().getName(), "child2.getParent()"); }
/* * Pour la détection de doublons, doit être appelé sur * le nœud racine pour une évaluation complète * */ public StringCollection checkDuplicates(ContainsNode rootNode, String excluded) { Dictionary <String, Int32> identifiers = new Dictionary <String, Int32>(); List <ContainsNode> lstNodes = new List <ContainsNode>(); getNodesList(rootNode, lstNodes); foreach (ContainsNode checkedNode in lstNodes) { checkedNode.findDuplicates(lstNodes, checkedNode, excluded, identifiers); } StringCollection duplicates = new StringCollection(); Dictionary <String, int> .KeyCollection keys = identifiers.Keys; foreach (String key in keys) { if (identifiers[key] > 1) { duplicates.Add("L'identifiant " + key + " n'est pas unique, il est utilisé " + identifiers[key] + " fois."); } } return(duplicates); }
public void C12_treeNbDocumentsTest() { ContainsNode root = new ContainsNode("root", null, true); ContainsNode n1 = root.addNewNode("n1", true); ContainsNode n11 = n1.addNewNode("n11", true); n11.incNbDocs(2); ContainsNode n12 = n1.addNewNode("n12", true); n11.incNbDocs(1); ContainsNode n2 = root.addNewNode("n2", true); n2.incNbDocs(1); ContainsNode n21 = n2.addNewNode("n21", true); n21.incNbDocs(5); ContainsNode n22 = n2.addNewNode("n22", true); Assert.AreEqual(9, root.computeNbDocuments(), "root.computeNbDocuments()"); Assert.AreEqual(9, root.getNbDocuments(), "root.getNbDocuments()"); int nbNodes = 1; // Au moins root ContainsNode node = root; while ((node = node.next()) != null) { nbNodes++; } Assert.AreEqual(7, nbNodes, "next()"); }
public void C13_treeNonMandatoryButNotEmptyTest() { ContainsNode root = new ContainsNode("root", null, true); ContainsNode n1 = root.addNewNode("n1", true); ContainsNode n11 = n1.addNewNode("n11", false); n11.incNbDocs(2); ContainsNode n12 = n1.addNewNode("n12", true); n11.incNbDocs(1); ContainsNode n2 = root.addNewNode("n2", false); n2.incNbDocs(1); ContainsNode n21 = n2.addNewNode("n21", true); n21.incNbDocs(5); ContainsNode n22 = n2.addNewNode("n22", true); Assert.AreEqual(9, root.computeNbDocuments(), "root.computeNbDocuments()"); Assert.AreEqual(9, root.getNbDocuments(), "root.getNbDocuments()"); root.trunkChildrenOfEmptyBranches(); int nbNodes = 1; // Au moins root ContainsNode node = root; while ((node = node.next()) != null) { nbNodes++; } Assert.AreEqual(7, nbNodes, "next()"); }
/* * Ajoute un nœud au nœud courant * */ public ContainsNode addNewNode(String newNodeId, bool bContainsIsMandatory) { int numeroTag = 0; if (newNodeId.EndsWith("+")) { numeroTag++; String nodeName = newNodeId.Substring(0, newNodeId.Length - 1); foreach (ContainsNode child in this.childrens) { // Le nom des frères peut commener par nodeName // Le nom du frère est donc de la forme nodeName[numero] String brotherName = child.getName(); Regex r = new Regex(nodeName + @"\[#(\d+)\]"); Match m = r.Match(brotherName); if (m.Success) { try { int newNumeroTag = Convert.ToInt32(m.Groups[1].ToString()) + 1; if (newNumeroTag > numeroTag) { numeroTag = newNumeroTag; } } catch (Exception e) { e.ToString(); } } } } if (numeroTag > 0) { newNodeId = newNodeId.Substring(0, newNodeId.Length - 1) + "[#" + numeroTag + "]"; } ContainsNode newNode = new ContainsNode(newNodeId, this, bContainsIsMandatory); this.childrens.Add(newNode); return(newNode); }
protected void recurseContainsDefine(String defineNodeName, String context, bool isRepeatable) { if (traceActions) tracesWriter.WriteLine("recurseContainsDefine ('" + defineNodeName + "', '" + context + "', '" + currentDocumentTypeId + "')"); String xPath; // Récupérer l'attribut schemeID de la balise ArchivalAgencyObjectIdentifier // et la mettre dans un arbre currentDocumentTypeId = missingString; if (context.Equals(String.Empty)) { currentDocumentTypeId = "root"; } else { // Tester la présence de ArchivalAgencyObjectIdentifier dans l'unité documentaire xPath = "rng:define[@name='" + defineNodeName + "']/rng:element[@name='ArchivalAgencyObjectIdentifier']/rng:ref"; XmlNode aaoirefNode = grammarNode.SelectSingleNode(xPath, docInXmlnsManager); if (aaoirefNode == null) { xPath = "rng:define[@name='" + defineNodeName + "']/rng:optional/rng:element[@name='ArchivalAgencyObjectIdentifier']/rng:ref"; aaoirefNode = grammarNode.SelectSingleNode(xPath, docInXmlnsManager); if (aaoirefNode != null) { String ret = getSchemeIdValue(aaoirefNode, xPath, context); if (ret != null) { errorsList.Add("La balise ArchivalAgencyObjectIdentifier de l'unité documentaire '" + ret + "' est optionnelle. Il faut la rendre obligatoire."); } } else errorsList.Add("La balise ArchivalAgencyObjectIdentifier de l'unité documentaire '" + currentDocumentTypeId + "' n'existe pas. Il faut la créer et la rendre obligatoire."); } else { String ret = getSchemeIdValue(aaoirefNode, xPath, context); if (ret != null) currentDocumentTypeId = ret; } checkForMultipleDocument(defineNodeName, context); checkForContentDescription(defineNodeName, context); checkForFilename(defineNodeName, context); checkForDocType(defineNodeName, context); // TODO: Désactivation du contrôle de la langue en attendant une meilleure gestion // checkForLanguage(defineNodeName, context); checkForDescriptionLevel(defineNodeName, context); } if (currentDocumentTypeId == "root") { rootContainsNode = new ContainsNode(currentDocumentTypeId, null, true); currentContainsNode = rootContainsNode; } else { currentContainsNode = currentContainsNode.addNewNode(currentDocumentTypeId, true); if ( isRepeatable && ! currentDocumentTypeId.EndsWith("+")) errorsList.Add("L'unité documentaire '" + currentDocumentTypeId + "' peut être répétée, mais elle ne possède pas de TAG répétable (TAG+). Il faut ajouter un '+' au tag ou changer les cardinalités"); if (! isRepeatable && currentDocumentTypeId.EndsWith("+")) errorsList.Add("L'unité documentaire '" + currentDocumentTypeId + "' est unique ou optionnelle, mais elle possède un TAG répétable (TAG+). Il faut supprimer le '+' du tag ou changer les cardinalités"); loadExpectedTagsInContainsNode(defineNodeName, currentDocumentTypeId); } xPath = "rng:define[@name='" + defineNodeName + "']"; XmlNode containsNode = grammarNode.SelectSingleNode(xPath, docInXmlnsManager); if (containsNode == null) { errorsList.Add("Le nœud '" + xPath + "' n'a pas été trouvé dans le profil '" + profileFile + "'"); } else { // Parcourir récursivement toutes les balises Contains filles xPath = "descendant::rng:element[@name='" + descendantContains + "']/rng:ref"; XmlNodeList containsNodesList = containsNode.SelectNodes(xPath, docInXmlnsManager); if (containsNodesList != null) { foreach (XmlNode node in containsNodesList) { String nodeName = node.Attributes.GetNamedItem("name").Value; if (nodeName == null) { errorsList.Add("Le nœud '" + xPath + "' n'a pas d'attribut name."); } else { bool bRepeatableContains = false; //<rng:element name="Contains"> // <rng:ref name="Contains_N68245"/> //</rng:element> //<rng:zeroOrMore> // <rng:element name="Contains"> // <rng:ref name="Contains_N68650"/> // </rng:element> //</rng:zeroOrMore> // on est sur le rng:ref, on remonte sur le parent rng:element // et on regarde si on a un parent nommé rng:zeroOrMore ou rng:oneOrMore xPath = "../.."; XmlNode parentNode = node.SelectSingleNode(xPath); String parentNodeStr = parentNode.Name; if (parentNodeStr == "rng:zeroOrMore" || parentNodeStr == "rng:oneOrMore") bRepeatableContains = true; recurseContainsDefine(nodeName, context + "/Contains", bRepeatableContains); } } } currentContainsNode = currentContainsNode.getParent(); } }
void doContains(XmlNode currentNode, ref int bGenererElement, ref bool boucleTags, int numeroTag, bool bContainsIsMandatory) { currentDocumentTypeId = lookupForContainsIdentifier(currentNode); if (traceActions) tracesWriter.WriteLineFlush("lookupForContainsIdentifier trouve currentDocumentTypeId " + currentDocumentTypeId + " en passe " + currentPass); if (currentDocumentTypeId.EndsWith("+")) { boucleTags = true; currentDocumentTypeId = formatContainsIdentifier(currentDocumentTypeId, numeroTag); if (traceActions) tracesWriter.WriteLineFlush("currentDocumentTypeId à répétition : " + currentDocumentTypeId); } bGenererElement = 1; // si on est sur une boucleTags, il faut s'arrêter au nombre maximum d'itérations // donc demander à ArchiveDocuments si il y a des références à e TAG numéroté if (boucleTags) if (archiveDocuments.IsThereDocumentsReferringToType(currentDocumentTypeId) == false) { bGenererElement = 0; boucleTags = false; } if (currentPass == 2) { if (bGenererElement > 0 && currentContainsNode != null) { if (currentDocumentTypeId == "root") currentContainsNode = rootContainsNode; else currentContainsNode = currentContainsNode.next(); if (currentContainsNode != null) { // Tant qu'on est pas rrivés au bout de l'arbre if (traceActions) tracesWriter.WriteLineFlush("Selecting next currentContainsNode " + currentContainsNode.getName() + " that contains " + currentContainsNode.getNbDocuments() + " documents"); int nbDocs = currentContainsNode.getNbDocuments(); bGenererElement = nbDocs > 0 ? 1 : 0; if (traceActions) tracesWriter.WriteLineFlush("DOCLIST docs " + currentDocumentTypeId + " contains " + nbDocs + " documents"); } } } else { if (bGenererElement != 0) { if (currentDocumentTypeId == "root") { currentContainsNode = rootContainsNode; } else { if (traceActions) tracesWriter.WriteLineFlush("création nouveau containsNode(" + currentDocumentTypeId + ")"); currentContainsNode = currentContainsNode.addNewNode(currentDocumentTypeId, bContainsIsMandatory); } int nbDocs = archiveDocuments.prepareListForType(currentContainsNode.getRelativeContext()); currentContainsNode.incNbDocs(nbDocs); } } }
/* * C'est le fichier de sortie qui contient le bordereau de transfert construit avec : * Exceptions : * - SedaSumGenNoInformationsException * - SedaSumGenNoArchiveDocumentsException * - SedaSumGenNoProfileException * * La séquence d'appels pour une production de bordereau est la suivante : * * SedaSummaryGenerator ssg = new SedaSummaryRngGenerator(); * ssg.setTracesWriter(streamWriter); * * ssg.prepareInformationsWithDatabase(informationsDatabase, accordVersement); * * ssg.prepareArchiveDocumentsWithFile("liste-fichiers.txt"); * * ssg.generateSummaryFile("bordereau.xml"); * * ssg.close(); * * errors = ssg.getErrorsList(); * * */ public override void generateSummaryFile(String summaryFile) { if (archiveDocumentsLoaded == false || profileLoaded == false || informationsLoaded == false) return; if (currentPass == 1) { if (traceActions) tracesWriter.WriteLineFlush("\n-----------------------------------------\n"); if (traceActions) tracesWriter.WriteLineFlush("Début de l'évaluation du nombre de documents"); if (traceActions) tracesWriter.WriteLineFlush("\n-----------------------------------------\n"); Console.WriteLine("Début de l'évaluation du nombre de documents"); } if (currentPass == 2) { if (traceActions) tracesWriter.WriteLineFlush("\n-----------------------------------------\n"); if (traceActions) tracesWriter.WriteLineFlush("Début de génération du bordereau"); if (traceActions) tracesWriter.WriteLineFlush("\n-----------------------------------------\n"); Console.WriteLine("Début de génération du bordereau"); // Create the XmlDocument. XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; docOut = XmlWriter.Create(summaryFile, settings); } try { if (currentPass == 2) docOut.WriteStartDocument(); grammarNode = docIn.SelectSingleNode("rng:grammar", docInXmlnsManager); XmlNode startNode = docIn.SelectSingleNode("rng:grammar/rng:start/rng:ref", docInXmlnsManager); if (grammarNode != null && startNode != null) { // SEDA 1.0 "fr:gouv:culture:archivesdefrance:seda:v1.0" // SEDA 0.2 "fr:gouv:ae:archive:draft:standard_echange_v0.2" String sTestSeda = grammarNode.Attributes.GetNamedItem("ns").Value; if (sTestSeda == "fr:gouv:ae:archive:draft:standard_echange_v0.2") { SEDA_version = "0.2"; } else if (sTestSeda == "fr:gouv:culture:archivesdefrance:seda:v1.0") { SEDA_version = "1.0"; } else { SEDA_version = "Version du SEDA inconnue"; errorsList.Add("Version du SEDA inconnue : '" + sTestSeda + "'"); } recurseDefine(startNode.Attributes.GetNamedItem("name").Value, ""); } else { if (currentPass == 2) { if (grammarNode == null) { errorsList.Add("Le nœud '" + "rng:grammar" + "' n'a pas été trouvé dans le profil '" + profileFile + "'"); } else { errorsList.Add("Le nœud '" + "rng:grammar/rng:start/rng:ref" + "' n'a pas été trouvé dans le profil '" + profileFile + "'"); } } } } catch (XPathException e) { if (traceActions) tracesWriter.WriteLineFlush("Exception XPath..."); if (traceActions) tracesWriter.WriteLineFlush(e.Message); if (currentPass == 2) errorsList.Add("generateSummaryFile :" + e.GetType().Name + " " + e.Message); } if (currentPass == 2) { docOut.WriteEndDocument(); docOut.Close(); } if (currentPass == 1) { if (traceActions) tracesWriter.WriteLineFlush("\n-----------------------------------------\n"); if (traceActions) tracesWriter.WriteLineFlush("Fin de l'évaluation du nombre de documents"); if (traceActions) tracesWriter.WriteLineFlush("\n-----------------------------------------\n"); Console.WriteLine("Fin de l'évaluation du nombre de documents"); rootContainsNode.computeNbDocuments(); if (traceActions) tracesWriter.WriteLineFlush(rootContainsNode.dump()); bool bAllMandatoryContainsHaveDocuments = true; String sListMandatoryContainsInError = String.Empty; if (traceActions) { ContainsNode node = rootContainsNode; while (node != null) { if (node.getMandatory() == true && node.getNbDocuments() == 0) { bAllMandatoryContainsHaveDocuments = false; sListMandatoryContainsInError += node.getName(); sListMandatoryContainsInError += "\t"; } tracesWriter.WriteLineFlush("next node = " + node.getName() + " docs = " + node.getNbDocuments() + " mandatory = " + node.getMandatory() ); node = node.next(); } } if (bAllMandatoryContainsHaveDocuments == false) { if (traceActions) tracesWriter.WriteLineFlush("Il existe des unités documentaires obligatoires sans documents : " + sListMandatoryContainsInError); errorsList.Add("Il existe des unités documentaires obligatoires sans documents : " + sListMandatoryContainsInError); } else { currentPass = 2; rootContainsNode.trunkChildrenOfEmptyBranches(); if (traceActions) tracesWriter.WriteLineFlush(rootContainsNode.dump()); currentContainsNode = rootContainsNode; firstContainsNode = true; // Indique que le prochain nœud Contains est le premier currentDocumentTypeId = "root"; generateSummaryFile(summaryFile); } } else { if (traceActions) tracesWriter.WriteLineFlush("\n-----------------------------------------\n"); if (traceActions) tracesWriter.WriteLineFlush("Fin de génération du bordereau"); if (traceActions) tracesWriter.WriteLineFlush("\n-----------------------------------------\n"); Console.WriteLine("Fin de génération du bordereau"); } }
/* * Ajoute un nœud au nœud courant * */ public ContainsNode addNewNode(String newNodeId, bool bContainsIsMandatory) { int numeroTag = 0; if (newNodeId.EndsWith("+")) { numeroTag++; String nodeName = newNodeId.Substring(0,newNodeId.Length-1); foreach (ContainsNode child in this.childrens) { // Le nom des frères peut commener par nodeName // Le nom du frère est donc de la forme nodeName[numero] String brotherName = child.getName(); Regex r = new Regex(nodeName + @"\[#(\d+)\]"); Match m = r.Match(brotherName); if (m.Success) { try { int newNumeroTag = Convert.ToInt32(m.Groups[1].ToString()) + 1; if (newNumeroTag > numeroTag) numeroTag = newNumeroTag; } catch (Exception e) { e.ToString(); } } } } if (numeroTag > 0) newNodeId = newNodeId.Substring(0, newNodeId.Length - 1) + "[#" + numeroTag + "]"; ContainsNode newNode = new ContainsNode(newNodeId, this, bContainsIsMandatory); this.childrens.Add(newNode); return newNode; }
/* * Écriture des balisesUniques d'un rng:element * Si le contenu fait appel à des rng:define peut appeler recurseDefine * * */ protected bool genElement(XmlNode elemNode, String tagToWrite, String context) { String dataString = null; int counter = 1; bool callNextDocument = false; if (tagToWrite == "Document") { if (currentDocumentTypeId != null) { String typeId = currentContainsNode.getRelativeContext(); String documentIdentification = lookupForDocumentIdentification(elemNode); bool withDocumentIdentification = documentIdentification != String.Empty; if (withDocumentIdentification) { typeId += "{" + documentIdentification + "}"; } counter = archiveDocuments.prepareListForType(typeId, withDocumentIdentification); if (traceActions) tracesWriter.WriteLineFlush("genElement Document : typeId " + typeId + " has " + counter + " documents"); callNextDocument = true; } } for (int bcl = 0; bcl < counter; ++bcl) { if (callNextDocument) archiveDocuments.nextDocument(); if (traceActions) tracesWriter.WriteLineFlush("genElement (" + elemNode.Name + ", " + tagToWrite + ", " + context + ")"); try { if (currentPass == 2) { if (tagToWrite == "ArchiveTransfer") { // SEDA 1.0 "fr:gouv:culture:archivesdefrance:seda:v1.0" // SEDA 0.2 "fr:gouv:ae:archive:draft:standard_echange_v0.2" docOut.WriteStartElement(tagToWrite, grammarNode.Attributes.GetNamedItem("ns").Value); } else docOut.WriteStartElement(tagToWrite); } } catch (InvalidOperationException e) { if (traceActions) tracesWriter.WriteLineFlush("Unable to write start element " + tagToWrite); if (traceActions) tracesWriter.WriteLineFlush(e.Message); } if (elemNode.HasChildNodes) { foreach (XmlNode node in elemNode.ChildNodes) { switch (node.Name) { case "rng:ref": String newContext = context + "/" + tagToWrite; if (node.Attributes != null) { if (node.Attributes.GetNamedItem("name").Value.Equals("anyElement")) dataString = getTag(tagToWrite, context); else recurseDefine(node.Attributes.GetNamedItem("name").Value, newContext); } break; case "rng:value": dataString = node.InnerText; break; case "rng:data": dataString = getTag(tagToWrite, context); break; default: if (traceActions) tracesWriter.WriteLineFlush("genElement ---- !!!! currentNode.Name Unhandled '" + node.Name + "' in context '" + context + "' for tag2write '" + tagToWrite + "'"); break; } } } try { if (dataString != null) if (currentPass == 2) docOut.WriteString(dataString); } catch (InvalidOperationException e) { if (traceActions) tracesWriter.WriteLineFlush("Unable to write string content " + dataString); if (traceActions) tracesWriter.WriteLineFlush(e.Message); } try { if (currentPass == 1) { // On redescend dans l'arbre des ContainsNode // en passe 2 on utilise la méthode next qui permet de parcurir l'arbre comme un vecteur if ((tagToWrite == "Contains" // SEDA 0.2 || tagToWrite == "ArchiveObject" || tagToWrite == "Archive") // SEDA 1.0 && currentContainsNode != rootContainsNode) currentContainsNode = currentContainsNode.getParent(); } if (currentPass == 2) docOut.WriteEndElement(); } catch (InvalidOperationException e) { if (traceActions) tracesWriter.WriteLineFlush("Unable to write end element " + tagToWrite); if (traceActions) tracesWriter.WriteLineFlush(e.Message); } } return true; }
/* * Création de la liste de tous les nœuds de l'arbre * */ protected void getNodesList(ContainsNode startNode, List<ContainsNode> lstNodes) { foreach (ContainsNode curNode in startNode.childrens) { lstNodes.Add(curNode); getNodesList(curNode, lstNodes); } }
protected void findDuplicates(List<ContainsNode> lstNodes, ContainsNode checkedNode, String excluded, Dictionary<String, Int32> identifiers) { // on ne teste que si on a atteint l'identifiant pour éviter de traiter tout l'arbre avec chaque identifiant bool bTester = false; foreach (ContainsNode curNode in lstNodes) { if (curNode != checkedNode) { if (bTester != false) continue; if (curNode.objectIdentifier.Equals(checkedNode.objectIdentifier)) if (!curNode.objectIdentifier.Equals(excluded)) { if (identifiers.ContainsKey(curNode.objectIdentifier)) { identifiers[curNode.objectIdentifier] = identifiers[curNode.objectIdentifier] + 1; } } } else { if (!identifiers.ContainsKey(curNode.objectIdentifier)) { identifiers.Add(curNode.objectIdentifier, 1); } bTester = true; } } }
/* * Pour la détection de doublons, doit être appelé sur * le nœud racine pour une évaluation complète * */ public StringCollection checkDuplicates(ContainsNode rootNode, String excluded) { Dictionary<String, Int32> identifiers = new Dictionary<String, Int32>(); List<ContainsNode> lstNodes = new List<ContainsNode>(); getNodesList(rootNode, lstNodes); foreach (ContainsNode checkedNode in lstNodes) { checkedNode.findDuplicates(lstNodes, checkedNode, excluded, identifiers); } StringCollection duplicates = new StringCollection(); Dictionary<String, int>.KeyCollection keys = identifiers.Keys; foreach (String key in keys) { if (identifiers[key] > 1) { duplicates.Add ("L'identifiant " + key + " n'est pas unique, il est utilisé " + identifiers[key] + " fois."); } } return duplicates; }
public void C15_getRelativeContextTest() { ContainsNode root = new ContainsNode("root", null, true); ContainsNode A_1 = root.addNewNode("A[#1]", true); ContainsNode AA_1 = A_1.addNewNode("AA", false); AA_1.addNewNode("AAA[#1]", true); AA_1.addNewNode("AAA[#2]", true); ContainsNode tst_1 = AA_1.addNewNode("AAA[#3]", true); ContainsNode BB_1 = A_1.addNewNode("BB", true); BB_1.addNewNode("BBB[#1]", true); ContainsNode tst_2 = BB_1.addNewNode("BBB[#2]", true); BB_1.addNewNode("BBB[#3]", true); ContainsNode A_2 = root.addNewNode("A[#2]", false); ContainsNode AA_2 = A_2.addNewNode("AA", false); ContainsNode tst_3 = AA_2.addNewNode("AAA[#1]", true); AA_2.addNewNode("AAA[#2]", true); AA_2.addNewNode("AAA[#3]", true); ContainsNode BB_2 = A_2.addNewNode("BB", true); BB_2.addNewNode("BBB[#1]", true); BB_2.addNewNode("BBB[#2]", true); BB_2.addNewNode("BBB[#3]", true); ContainsNode tst_4 = BB_2.addNewNode("BBB[#4]", true); Assert.AreEqual("A[#1]//AAA[#3]", tst_1.getRelativeContext(), false, "tst_1.getRelativeContext()"); Assert.AreEqual("A[#1]//BBB[#2]", tst_2.getRelativeContext(), false, "tst_2.getRelativeContext()"); Assert.AreEqual("A[#2]//AAA[#1]", tst_3.getRelativeContext(), false, "tst_3.getRelativeContext()"); Assert.AreEqual("A[#2]//BBB[#4]", tst_4.getRelativeContext(), false, "tst_4.getRelativeContext()"); }