/// <summary>
        /// Remove the namespace declarations from the specified <see cref="Stream"/> <paramref name="value"/>.
        /// </summary>
        /// <param name="value">An XML <see cref="Stream"/> to purge namespace declarations from.</param>
        /// <param name="omitXmlDeclaration">if set to <c>true</c> omit the XML declaration; otherwise <c>false</c>. The default is false.</param>
        /// <param name="encoding">The text encoding to use.</param>
        /// <returns>A <see cref="Stream"/> object representing the specified <paramref name="value"/> but with no namespace declarations.</returns>
        public static Stream RemoveNamespaceDeclarations(Stream value, bool omitXmlDeclaration, Encoding encoding)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }
            IXPathNavigable navigable = XPathNavigableConverter.FromStream(value, true); // todo: leaveStreamOpen
            XPathNavigator  navigator = navigable.CreateNavigator();
            MemoryStream    output;
            MemoryStream    tempOutput = null;

            try
            {
                tempOutput = new MemoryStream();
                using (XmlWriter writer = XmlWriter.Create(tempOutput, XmlWriterUtility.CreateSettings(o =>
                {
                    o.Encoding = encoding;
                    o.OmitXmlDeclaration = omitXmlDeclaration;
                })))
                {
                    WriteElements(navigator, writer);
                    writer.Flush();
                }
                output          = tempOutput;
                output.Position = 0;
                tempOutput      = null;
            }
            finally
            {
                if (tempOutput != null)
                {
                    tempOutput.Dispose();
                }
            }
            return(output);
        }
        /// <summary>
        /// Revert the obfuscated XML document of <paramref name="value"/> to its original state by applying the mappaple XML document of <paramref name="mapping"/>.
        /// </summary>
        /// <param name="value">The obfuscated <see cref="Stream"/> to revert.</param>
        /// <param name="mapping">A <see cref="Stream"/> containing mappaple values necessary to revert <paramref name="value"/> to its original state.</param>
        /// <returns>A <see cref="Stream"/> object where the obfuscated XML document has been reverted to its original XML document.</returns>
        public override Stream Revert(Stream value, Stream mapping)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }
            if (mapping == null)
            {
                throw new ArgumentNullException(nameof(mapping));
            }
            long obfustatedStartingPosition = -1;
            long mappingStartingPosition    = -1;

            if (value.CanSeek)
            {
                obfustatedStartingPosition = value.Position;
                value.Position             = 0;
            }
            if (mapping.CanSeek)
            {
                mappingStartingPosition = mapping.Position;
                mapping.Position        = 0;
            }

            IXPathNavigable document     = XPathNavigableConverter.FromStream(mapping);
            XPathNavigator  navigator    = document.CreateNavigator();
            string          mappingXpath = string.Format(CultureInfo.InvariantCulture, "{0}/{1}[@{2}='{3}']", MappingRootElement, MappingValueElement, MappingMapsToAttribute, "{0}");

            MemoryStream output;
            MemoryStream tempOutput = null;

            try
            {
                tempOutput = new MemoryStream();
                using (XmlWriter writer = XmlWriter.Create(tempOutput, XmlWriterUtility.CreateSettings(o => o.Encoding = Encoding)))
                {
                    using (XmlReader reader = XmlReader.Create(value))
                    {
                        while (reader.Read())
                        {
                            bool writeEndElement = false;
                            switch (reader.NodeType)
                            {
                            case XmlNodeType.Attribute:
                                writer.WriteAttributeString(reader.Prefix, Exclusions.Contains(reader.LocalName) ? reader.LocalName : navigator.SelectSingleNode(string.Format(CultureInfo.InvariantCulture, mappingXpath, reader.LocalName)).Value, reader.NamespaceURI, Exclusions.Contains(reader.Value) ? reader.Value : navigator.SelectSingleNode(string.Format(CultureInfo.InvariantCulture, "{0}/{1}[@{2}='{3}']", MappingRootElement, MappingValueElement, MappingMapsToAttribute, reader.Value)).Value);
                                while (reader.MoveToNextAttribute())
                                {
                                    goto case XmlNodeType.Attribute;
                                }
                                reader.MoveToElement();
                                break;

                            case XmlNodeType.Element:
                                writer.WriteStartElement(reader.Prefix, Exclusions.Contains(reader.LocalName) ? reader.LocalName : navigator.SelectSingleNode(string.Format(CultureInfo.InvariantCulture, mappingXpath, reader.LocalName)).Value, reader.NamespaceURI);
                                writeEndElement = reader.IsEmptyElement;
                                if (reader.HasAttributes)
                                {
                                    if (reader.MoveToFirstAttribute())
                                    {
                                        goto case XmlNodeType.Attribute;
                                    }
                                }
                                break;

                            case XmlNodeType.EndElement:
                                writer.WriteFullEndElement();
                                break;

                            case XmlNodeType.Comment:
                                writer.WriteComment(reader.Value);
                                break;

                            case XmlNodeType.DocumentType:
                                writer.WriteDocType(reader.Name, reader.GetAttribute("PUBLIC"), reader.GetAttribute("SYSTEM"), reader.Value);
                                break;

                            case XmlNodeType.XmlDeclaration:
                            case XmlNodeType.ProcessingInstruction:
                                writer.WriteProcessingInstruction(reader.Name, reader.Value);
                                break;

                            case XmlNodeType.Text:
                                writer.WriteString(Exclusions.Contains(reader.Value) ? reader.Value : navigator.SelectSingleNode(string.Format(CultureInfo.InvariantCulture, mappingXpath, reader.Value)).Value);
                                break;

                            case XmlNodeType.Whitespace:
                            case XmlNodeType.SignificantWhitespace:
                                writer.WriteWhitespace(reader.Value);
                                break;

                            case XmlNodeType.CDATA:
                                writer.WriteCData(Exclusions.Contains(reader.Value) ? reader.Value : navigator.SelectSingleNode(string.Format(CultureInfo.InvariantCulture, mappingXpath, reader.Value)).Value);
                                break;

                            case XmlNodeType.EntityReference:
                                writer.WriteEntityRef(reader.Name);
                                break;
                            }
                            if (writeEndElement)
                            {
                                writer.WriteEndElement();
                            }
                        }
                    }
                    writer.Flush();
                }
                tempOutput.Position = 0;
                output     = tempOutput;
                tempOutput = null;
            }
            finally
            {
                if (tempOutput != null)
                {
                    tempOutput.Dispose();
                }
            }

            if (value.CanSeek)
            {
                value.Seek(obfustatedStartingPosition, SeekOrigin.Begin);
            }
            if (mapping.CanSeek)
            {
                mapping.Seek(mappingStartingPosition, SeekOrigin.Begin);
            }

            return(output);
        }
Beispiel #3
0
        /// <summary>
        /// Returns a JSON representation of the specified XML stream and whose value is equivalent to the specified XML stream.
        /// </summary>
        /// <param name="value">The XML to convert to a JSON representation.</param>
        /// <param name="encoding">The text encoding to use.</param>
        /// <returns>A JSON representation of the specified <paramref name="value"/> and whose value is equivalent to <paramref name="value"/>.</returns>
        /// <exception cref="ArgumentOutOfRangeException">This exception is thrown when <paramref name="encoding"/> is not within the boundaries of RFC 4627.</exception>
        /// <exception cref="ArgumentNullException">This exception is thrown should either of <paramref name="value"/> or <paramref name="encoding"/> have the value of null.</exception>
        /// <remarks>The JSON representation is in compliance with RFC 4627. Take note, that all string values is escaped using <see cref="StringUtility.Escape"/>. This is by design and to help ensure compatibility with a wide range of data.</remarks>
        public static Stream FromXmlStream(Stream value, Encoding encoding)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }
            if (encoding == null)
            {
                throw new ArgumentNullException(nameof(encoding));
            }
            JsonWriter.ValidateEncoding(encoding);

            long startingPosition = value.Position;

            if (value.CanSeek)
            {
                value.Position = 0;
            }

            MemoryStream output     = null;
            MemoryStream tempOutput = null;

            try
            {
                tempOutput = new MemoryStream();
                using (JsonWriter writer = JsonWriter.Create(tempOutput, encoding))
                {
                    IXPathNavigable   navigable     = XPathNavigableConverter.FromStream(value);
                    XPathNavigator    rootNavigator = navigable.CreateNavigator();
                    XPathNodeIterator rootIterator  = rootNavigator.Select("/node()");

                    XmlJsonInstance instance = BuildJsonInstance(rootIterator);
                    writer.WriteStartObject();
                    WriteJsonInstance(writer, instance);
                    writer.WriteEndObject();

                    writer.Flush();
                    tempOutput.Position = 0;
                    output     = new MemoryStream(tempOutput.ToArray());
                    tempOutput = null;
                }
            }
            catch (Exception)
            {
                if (output != null)
                {
                    output.Dispose();
                }
                throw;
            }
            finally
            {
                if (tempOutput != null)
                {
                    tempOutput.Dispose();
                }
            }

            if (value.CanSeek)
            {
                value.Seek(startingPosition, SeekOrigin.Begin);
            }                                                                      // reset to original position
            return(output);
        }