/// <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); }
/// <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); }