Add An XML Declaration To String Of XML - c#

I have some xml data that looks like..
<Root>
<Data>Nack</Data>
<Data>Nelly</Data>
</Root>
I want to add "<?xml version=\"1.0\"?>" to this string. Then preserve the xml as a string.
I attempted a few things..
This breaks and loses the original xml string
myOriginalXml="<?xml version=\"1.0\"?>" + myOriginalXml;
This doesnt do anything, just keeps the original xml data with no declaration attached.
XmlDocument doc = new XmlDocument();
doc.LoadXml(myOriginalXml);
XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "UTF-8","no");
StringWriter sw = new StringWriter();
XmlTextWriter tx = new XmlTextWriter(sw);
doc.WriteTo(tx);
string xmlString = sw.ToString();
This is also not seeming to have any effect..
XmlDocument doc = new XmlDocument();
doc.LoadXml(myOriginalXml);
XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "UTF-8", "no");
MemoryStream xmlStream = new MemoryStream();
doc.Save(xmlStream);
xmlStream.Flush();
xmlStream.Position = 0;
doc.Load(xmlStream);
StringWriter sw = new StringWriter();
XmlTextWriter tx = new XmlTextWriter(sw);
doc.WriteTo(tx);
string xmlString = sw.ToString();

Use an xmlwritersettings to achieve greater control over saving. The XmlWriter.Create accepts that setting (instead of the default contructor)
var myOriginalXml = #"<Root>
<Data>Nack</Data>
<Data>Nelly</Data>
</Root>";
var doc = new XmlDocument();
doc.LoadXml(myOriginalXml);
var ms = new MemoryStream();
var tx = XmlWriter.Create(ms,
new XmlWriterSettings {
OmitXmlDeclaration = false,
ConformanceLevel= ConformanceLevel.Document,
Encoding = UTF8Encoding.UTF8 });
doc.Save(tx);
var xmlString = UTF8Encoding.UTF8.GetString(ms.ToArray());

Related

convert json to xml and save result to a file

I'm converting a JSON string to an XML node like this:
public ActionResult Test(string json)
{
System.Xml.XmlNode myXmlNode = JsonConvert.DeserializeXmlNode("{\"root\":" + json + "}", "root");
How can I save myXmlNode to an external file, say test.xml?
Thanks
This should do it:
var xdoc = XDocument.Load(new StringReader(myXmlNode.ToString()), LoadOptions.None);
xdoc.Save(#"c:\temp\test.xml", SaveOptions.None);
UPDATE:
using (StreamWriter writer = new StreamWriter(Server.MapPath("~/test.xml")))
{
writer.WriteLine(myXmlNode.OuterXml);
}
XmlDocument doc = new XmlDocument();
doc.LoadXml(myXmlNode);
XmlTextWriter writer = new XmlTextWriter("yourfilename.xml",null);
writer.Formatting = Formatting.Indented;
doc.Save(writer);

How to create an XSLT stylesheet

I have access to Schematron xsl files and a Schematron sch file. How can I transform this into an XSLT stylesheet using C# ?
xsl + sch --> [??? XSLT Processor ??? ] --> xslt stylesheet
To answer my own question...
This works, unfortunately the Schematron files only support a very simple syntax using XslCompiledTransform. On to SAXON to see it that works :(
string xmlFile = #"sch\patient.sch";
string xslFile = #"xsl\conformance1-5.xsl";
XslCompiledTransform xsltransform = new XslCompiledTransform();
xsltransform.Load(xslFile);
XmlDocument doc = new XmlDocument();
doc.Load(xmlFile);
XPathNavigator nav = doc.CreateNavigator();
System.IO.MemoryStream st = new System.IO.MemoryStream();
xsltransform.Transform(nav, null, st);
st.Position = 0;
System.IO.StreamReader rd = new System.IO.StreamReader(st);
string xslt = rd.ReadToEnd();
System.Diagnostics.Debug.WriteLine(xslt);
XmlReader reader = XmlReader.Create(new System.IO.StringReader(xslt));
xsltransform.Load(reader);
var patient = PatientFactory.GeneratePatientBySOAPClasses();
patient.identifier[0].period.end.value = DateTime.Now.ToString("yyyy-MM-dd");
patient.identifier[0].period.start.value = DateTime.Now.AddYears(15).ToString("yyyy-MM-dd");
patient.identifier[0].period.start = null;
string xml = Serialization.SerializeXML(patient, "http://hl7.org/fhir");
xml = xml.Replace("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://hl7.org/fhir\"", "");
doc.LoadXml(xml);
nav = doc.CreateNavigator();
st = new System.IO.MemoryStream();
xsltransform.Transform(nav, null, st);
st.Position = 0;
rd = new System.IO.StreamReader(st);
string scematronresult = rd.ReadToEnd();

Decode & from & from XML with ToString()

How do I get the code below to return the desired output. This is just plain csharp in a main, no ASP.NET.
//Desired output: <amp>Before & After</amp>
//instead of
//Current output: <amp>Before & After</amp>
static void Main(string[] args)
{
string amp = "Before & After";
XmlDocument doc = new XmlDocument();
StringBuilder sb = new StringBuilder();
StringWriter stringWriter = new StringWriter(sb);
XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter);
xmlWriter.WriteStartElement("amp");
xmlWriter.WriteString(amp);
xmlWriter.WriteEndElement();
global::System.Windows.Forms.MessageBox.Show(sb.ToString());
}
Here is how I solved the particular problem.
string amp = "Before & After";
XmlDocument doc = new XmlDocument();
StringBuilder sb = new StringBuilder();
StringWriter stringWriter = new StringWriter(sb);
XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter);
xmlWriter.WriteStartElement("amp");
xmlWriter.WriteString(amp);
xmlWriter.WriteEndElement();
StringReader valueStringReader = new StringReader(sb.ToString());
XmlTextReader valueXmlReader = new XmlTextReader(valueStringReader);
valueXmlReader.MoveToContent();
global::System.Windows.Forms.MessageBox.Show(valueXmlReader.ReadString());
If you want invalid XML create it yourself.
string amp = "Before & After";
// don't really do this, it's very wrong
StringBuilder sb = new StringBuilder();
sb.Append("<amp>");
sb.Append(amp);
sb.Append("</amp>");
Console.WriteLine(sb);
But this is NOT valid xml, so don't do it. If you want to use XML, you need to use valid XML. Your original code sample is correct.
If you want something that is more human readable, then don't use XML, use YAML.
http://www.yaml.org/
amp: Before & After
The desired output is not valid XML. The current output is identical to a CDATA section in that Before & After and <![CDATA[Before & After]]> are simply two different ways of escaping an ampersand so that you can have valid XML. In either case, if you use any XML parser to read the content of the <amp> tag, it will return Before & After.
You could put your text into a CDataSection - see XmlDocument.CreateCDataSection.
Here is how I solved the particular problem.
string amp = "Before & After";
XmlDocument doc = new XmlDocument();
StringBuilder sb = new StringBuilder();
StringWriter stringWriter = new StringWriter(sb);
XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter);
xmlWriter.WriteStartElement("amp");
xmlWriter.WriteString(amp);
xmlWriter.WriteEndElement();
StringReader valueStringReader = new StringReader(sb.ToString());
XmlTextReader valueXmlReader = new XmlTextReader(valueStringReader);
valueXmlReader.MoveToContent();
global::System.Windows.Forms.MessageBox.Show(valueXmlReader.ReadString());

How to create an XML document from a .NET object?

I have the following variable that accepts a file name:
var xtr = new XmlTextReader(xmlFileName) { WhitespaceHandling = WhitespaceHandling.None };
var xd = new XmlDocument();
xd.Load(xtr);
I would like to change it so that I can pass in an object. I don't want to have to serialize the object to file first.
Is this possible?
Update:
My original intentions were to take an xml document, merge some xslt (stored in a file), then output and return html... like this:
public string TransformXml(string xmlFileName, string xslFileName)
{
var xtr = new XmlTextReader(xmlFileName) { WhitespaceHandling = WhitespaceHandling.None };
var xd = new XmlDocument();
xd.Load(xtr);
var xslt = new System.Xml.Xsl.XslCompiledTransform();
xslt.Load(xslFileName);
var stm = new MemoryStream();
xslt.Transform(xd, null, stm);
stm.Position = 1;
var sr = new StreamReader(stm);
xtr.Close();
return sr.ReadToEnd();
}
In the above code I am reading in the xml from a file. Now what I would like to do is just work with the object, before it was serialized to the file.
So let me illustrate my problem using code
public string TransformXMLFromObject(myObjType myobj , string xsltFileName)
{
// Notice the xslt stays the same.
// Its in these next few lines that I can't figure out how to load the xml document (xd) from an object, and not from a file....
var xtr = new XmlTextReader(xmlFileName) { WhitespaceHandling = WhitespaceHandling.None };
var xd = new XmlDocument();
xd.Load(xtr);
}
You want to turn an arbitrary .NET object into a serialized XML string? Nothing simpler than that!! :-)
public string SerializeToXml(object input)
{
XmlSerializer ser = new XmlSerializer(input.GetType(), "http://schemas.yournamespace.com");
string result = string.Empty;
using(MemoryStream memStm = new MemoryStream())
{
ser.Serialize(memStm, input);
memStm.Position = 0;
result = new StreamReader(memStm).ReadToEnd();
}
return result;
}
That should to it :-) Of course you might want to make the default XML namespace configurable as a parameter, too.
Or do you want to be able to create an XmlDocument on top of an existing object?
public XmlDocument SerializeToXmlDocument(object input)
{
XmlSerializer ser = new XmlSerializer(input.GetType(), "http://schemas.yournamespace.com");
XmlDocument xd = null;
using(MemoryStream memStm = new MemoryStream())
{
ser.Serialize(memStm, input);
memStm.Position = 0;
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreWhitespace = true;
using(var xtr = XmlReader.Create(memStm, settings))
{
xd = new XmlDocument();
xd.Load(xtr);
}
}
return xd;
}
You can serialize directly into the XmlDocument:
XmlDocument doc = new XmlDocument();
XPathNavigator nav = doc.CreateNavigator();
using (XmlWriter w = nav.AppendChild())
{
XmlSerializer ser = new XmlSerializer(typeof(MyType));
ser.Serialize(w, myObject);
}
Expanding on #JohnSaunders solution I wrote the following generic function:
public XmlDocument SerializeToXml<T>(T source) {
var document = new XmlDocument();
var navigator = document.CreateNavigator();
using (var writer = navigator.AppendChild()) {
var serializer = new XmlSerializer(typeof(T));
serializer.Serialize(writer, source);
}
return document;
}

How can I remove the BOM from XmlTextWriter using C#?

How do remove the BOM from an XML file that is being created?
I have tried using the new UTF8Encoding(false) method, but it doesn't work. Here is the code I have:
XmlDocument xmlDoc = new XmlDocument();
XmlTextWriter xmlWriter = new XmlTextWriter(filename, new UTF8Encoding(false));
xmlWriter.Formatting = Formatting.Indented;
xmlWriter.WriteProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
xmlWriter.WriteStartElement("items");
xmlWriter.Close();
xmlDoc.Load(filename);
XmlNode root = xmlDoc.DocumentElement;
XmlElement item = xmlDoc.CreateElement("item");
root.AppendChild(item);
XmlElement itemCategory = xmlDoc.CreateElement("category");
XmlText itemCategoryText = xmlDoc.CreateTextNode("test");
item.AppendChild(itemCategory);
itemCategory.AppendChild(itemCategoryText);
xmlDoc.Save(filename);
You're saving the file twice - once with XmlTextWriter and once with xmlDoc.Save. Saving from the XmlTextWriter isn't adding a BOM - saving with xmlDoc.Save is.
Just save to a TextWriter instead, so that you can specify the encoding again:
using (TextWriter writer = new StreamWriter(filename, false,
new UTF8Encoding(false))
{
xmlDoc.Save(writer);
}
I'd write the XML to a string(builder) instead and then write that string to file.

Categories