/// <summary> /// /// </summary> /// <param name="argNamespaceURI"></param> /// <param name="argMappingStack"></param> /// <returns></returns> private XmlNamespaceWrap GetNamespaceWrap(string argNamespaceURI, Stack <List <XmlNamespaceWrap> > argMappingStack) { XmlNamespaceWrap result = null; for (int stackCounter = argMappingStack.Count - 1; stackCounter >= 0 && result == null; stackCounter--) { List <XmlNamespaceWrap> elementMappingList = argMappingStack.ElementAt(stackCounter); for (int elementCounter = 0; elementCounter < elementMappingList.Count && result == null; elementCounter++) { XmlNamespaceWrap mapping = elementMappingList[elementCounter]; if (string.Compare(argNamespaceURI, mapping.NamespaceURI) == 0) { result = mapping; } } } return(result); }
//TODO: refactoring private void Steps(XmlReader readerLoc) { Stack <List <XmlNamespaceWrap> > namespacesStack = new Stack <List <XmlNamespaceWrap> >(); List <XmlNamespaceWrap> localNamespaces = new List <XmlNamespaceWrap>(); List <XmlAttributeWrap> localAttributes = new List <XmlAttributeWrap>(); int globalPrefixCounter = 1; // Parse the file. while (readerLoc.Read()) { if (readerLoc.NodeType == XmlNodeType.XmlDeclaration) { } else if (readerLoc.NodeType == XmlNodeType.Whitespace) { } else if (readerLoc.NodeType == XmlNodeType.ProcessingInstruction) { } else if (readerLoc.NodeType == XmlNodeType.Element) { if (readerLoc.IsStartElement()) { localNamespaces = new List <XmlNamespaceWrap>(); namespacesStack.Push(localNamespaces); localAttributes = new List <XmlAttributeWrap>(); List <XmlNamespaceWrap> unusedNamespaces = new List <XmlNamespaceWrap>(); XmlElementWrap startElement = new XmlElementWrap(readerLoc.Prefix, readerLoc.LocalName, GetNamespaceUri(readerLoc.NamespaceURI)); for (int i = 0; i < readerLoc.AttributeCount; i++) { readerLoc.MoveToAttribute(i); // Namespace; if (string.Compare(readerLoc.Prefix, "xmlns", StringComparison.InvariantCultureIgnoreCase) == 0) { } else if (string.IsNullOrEmpty(readerLoc.Prefix) && string.Compare(readerLoc.LocalName, "xmlns", StringComparison.InvariantCultureIgnoreCase) == 0) { } else { XmlAttributeWrap att = new XmlAttributeWrap(readerLoc.Prefix, readerLoc.LocalName, readerLoc.NamespaceURI, readerLoc.Value); if (string.IsNullOrEmpty(readerLoc.NamespaceURI)) { att.NamespaceURI = GetNamespaceUri(startElement.NamespaceURI); } localAttributes.Add(att); } } string elementNamespace = this.GetNamespaceUri(startElement.NamespaceURI); XmlNamespaceWrap elementPrefixNamespace = this.GetNamespaceWrap(elementNamespace, namespacesStack); string elementPrefix = elementPrefixNamespace != null ? elementPrefixNamespace.Prefix : string.Empty; if (string.IsNullOrEmpty(elementPrefix)) { elementPrefix = "ns" + globalPrefixCounter; globalPrefixCounter++; localNamespaces.Add(new XmlNamespaceWrap(elementPrefix, elementNamespace)); XmlAttributeWrap att = new XmlAttributeWrap("xmlns", elementPrefix, "http://www.w3.org/2000/xmlns/", elementNamespace); localAttributes.Add(att); } else { if (elementPrefixNamespace.Added == false) { elementPrefixNamespace.Added = true; XmlAttributeWrap att = new XmlAttributeWrap("xmlns", elementPrefix, "http://www.w3.org/2000/xmlns/", elementNamespace); localAttributes.Add(att); } } for (int k = 0; k < unusedNamespaces.Count; k++) { if (unusedNamespaces[k].NamespaceURI == elementNamespace) { unusedNamespaces.RemoveAt(k); break; } } writer.WriteStartElement(elementPrefix, startElement.LocalName, elementNamespace); List <XmlAttributeWrap> addAttrs = new List <XmlAttributeWrap>(); AttributeSortingComparer comparatorPrev = new AttributeSortingComparer(); localAttributes.Sort(comparatorPrev); foreach (XmlAttributeWrap tmpAtt in localAttributes) { if (string.Compare(tmpAtt.Prefix, "xmlns", StringComparison.InvariantCultureIgnoreCase) != 0) { string attributeNamespace = this.GetNamespaceUri(tmpAtt.NamespaceURI); //string attributePrefix = this.FindPrefix(attributeNamespace, namespacesStack); XmlNamespaceWrap attPrefixNamespace = this.GetNamespaceWrap(attributeNamespace, namespacesStack); string attributePrefix = (attPrefixNamespace != null) && (attPrefixNamespace.Prefix != null) ? attPrefixNamespace.Prefix : string.Empty; if (string.IsNullOrEmpty(attributePrefix)) { attributePrefix = "ns" + globalPrefixCounter; globalPrefixCounter++; localNamespaces.Add(new XmlNamespaceWrap(attributePrefix, attributeNamespace)); XmlAttributeWrap att = new XmlAttributeWrap("xmlns", attributePrefix, "http://www.w3.org/2000/xmlns/", attributeNamespace); addAttrs.Add(att); } else { if (attPrefixNamespace.Added == false) { attPrefixNamespace.Added = true; XmlAttributeWrap att = new XmlAttributeWrap("xmlns", attributePrefix, "http://www.w3.org/2000/xmlns/", attributeNamespace); localAttributes.Add(att); } } if (string.IsNullOrEmpty(tmpAtt.Prefix) == false) { tmpAtt.Prefix = attributePrefix; } tmpAtt.NamespaceURI = attributeNamespace; for (int k = 0; k < unusedNamespaces.Count; k++) { if (unusedNamespaces[k].NamespaceURI == attributeNamespace) { unusedNamespaces.RemoveAt(k); break; } } } } if (addAttrs.Count > 0) { localAttributes.AddRange(addAttrs); } if (unusedNamespaces.Count > 0) { List <string> forDelete = unusedNamespaces.Select(ns => ns.NamespaceURI).ToList(); for (int k = localAttributes.Count - 1; k >= 0; k--) { if (forDelete.Contains(localAttributes[k].Value)) { localAttributes.RemoveAt(k); } } for (int k = localNamespaces.Count - 1; k >= 0; k--) { if (forDelete.Contains(localNamespaces[k].NamespaceURI)) { localNamespaces[k].Added = false; } } } AttributeSortingComparer comparator = new AttributeSortingComparer(); localAttributes.Sort(comparator); localAttributes = comparator.SortXmlns(localAttributes, elementPrefix); foreach (XmlAttributeWrap tmpAtt in localAttributes) { if (string.IsNullOrEmpty(tmpAtt.Prefix)) { writer.WriteAttributeString(tmpAtt.LocalName, tmpAtt.Value); } else { writer.WriteAttributeString(tmpAtt.Prefix, tmpAtt.LocalName, tmpAtt.NamespaceURI, tmpAtt.Value); } } } } else if (readerLoc.NodeType == XmlNodeType.EndElement) { namespacesStack.Pop(); writer.WriteFullEndElement(); } else if (readerLoc.NodeType == XmlNodeType.Attribute) { writer.WriteAttributeString(readerLoc.Prefix, readerLoc.LocalName, readerLoc.NamespaceURI, readerLoc.Value); } else if (readerLoc.NodeType == XmlNodeType.CDATA) { writer.WriteCData(readerLoc.Value); } else if (readerLoc.NodeType == XmlNodeType.Text) { writer.WriteString(readerLoc.Value); } } writer.Flush(); }