Esempio n. 1
0
        private void ProcessAttributes(XmlReader reader, XmlWriter writer, string elementNS)
        {
            var    attrs      = new List <XmlAttributeInfo>();
            var    namespaces = new List <string>();
            bool   found;
            string prefix;

            reader.MoveToFirstAttribute();
            do
            {
                if (reader.NamespaceURI == W3NAMESPACE.NAME)
                {
                    if (reader.Value == elementNS)
                    {
                        // если это пространство имен элемента, то оно записывается отдельно первым - правило 7
                        continue;
                    }
                    else
                    {
                        // добавление для дальнейшей сортировки
                        namespaces.Add(reader.Value);
                    }
                }
                else
                {
                    // добавление для дальнейшей сортировки
                    attrs.Add(new XmlAttributeInfo(reader));
                }
            }while (reader.MoveToNextAttribute());

            attrs.Sort();
            namespaces.Sort();

            foreach (var ns in namespaces)
            {
                // объявление пространства имен только если оно используется - правило 4
                if (attrs.Exists(a => a.NamespaceURI.Equals(ns)))
                {
                    found = this.GetNamespacePrefix(ns, out prefix);
                    if (!found)
                    {
                        // объявление пространства имен только если оно не было уже объявлено - правило 5
                        WriteNSAttribute(writer, ns, prefix);
                    }
                }
            }

            foreach (var ai in attrs)
            {
                if (string.IsNullOrEmpty(ai.NamespaceURI))
                {
                    // запись unqualified атрибута
                    writer.WriteStartAttribute(null, ai.LocalName, null);
                }
                else
                {
                    // запись qualified атрибута с префиксом - он уже должен быть объявлен
                    this.GetNamespacePrefix(ai.NamespaceURI, out prefix);
                    writer.WriteStartAttribute(prefix, ai.LocalName, ai.NamespaceURI);
                }

                UnescapedGtWriter.WriteString(writer, ai.Value, this.UseOldEscaping, true);
                writer.WriteEndAttribute();
            }

            reader.MoveToElement();
        }
Esempio n. 2
0
        /// <summary>
        /// Главный метод преобразования
        /// </summary>
        private void DoSmevTransform()
        {
            if (this.innerDoc == null)
            {
                throw new InvalidOperationException("Not initalized");
            }

            var settings = new XmlWriterSettings()
            {
                NewLineHandling    = System.Xml.NewLineHandling.None, // по умолчанию - replace
                OmitXmlDeclaration = true,                            // правило 1 - удаление заголовка XML
                ConformanceLevel   = System.Xml.ConformanceLevel.Fragment,
                Encoding           = new UTF8Encoding(false)
            };

            this.outputStream = new MemoryStream();
            var writer = XmlWriter.Create(this.outputStream, settings);

            this.namespaceMapping.Clear();
            this.nsCount      = 0;
            this.currentLevel = 0;

            using (var reader = new XmlNodeReader(this.innerDoc))
            {
                while (reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.XmlDeclaration:
                    case XmlNodeType.Comment:
                    case XmlNodeType.ProcessingInstruction:
                        // правило 1 - удаление комментариев и инструкций
                        break;

                    case XmlNodeType.Element:
                        this.CurrentLevel++;
                        var elementNS = reader.NamespaceURI;
                        if (!String.IsNullOrEmpty(elementNS))
                        {
                            string prefix;
                            // правило 6 - проверка префикса и генерация его в случае необходимости
                            var found = this.GetNamespacePrefix(elementNS, out prefix);
                            writer.WriteStartElement(prefix, reader.LocalName, elementNS);
                            if (!found)
                            {
                                // правило 5 - объявление необъявленного пространства имен
                                WriteNSAttribute(writer, elementNS, prefix);
                            }
                        }
                        else
                        {
                            writer.WriteStartElement(reader.LocalName);
                        }
                        if (reader.HasAttributes)
                        {
                            // обработка правил 4,7 и 8
                            this.ProcessAttributes(reader, writer, elementNS);
                        }

                        // правило 3 - преобразование в пару start-tag + end-tag
                        if (reader.IsEmptyElement)
                        {
                            writer.WriteFullEndElement();
                            this.CurrentLevel--;
                        }
                        break;

                    case XmlNodeType.Text:
                        // правило 2 - удаление значений из пробельных символов
                        if (!string.IsNullOrEmpty(reader.Value.Trim()))
                        {
                            UnescapedGtWriter.WriteString(writer, reader.Value, this.UseOldEscaping, false);
                        }
                        break;

                    case XmlNodeType.EndElement:
                        writer.WriteFullEndElement();
                        this.CurrentLevel--;
                        break;
                    }
                }

                writer.Flush();
            }
        }