SqlXml removes XML header when comes from string - c#

I'm developing a web app with C# and MVC4. Currently I'm working in converting string vars to SqlXml files. I have a XML file with this structure:
<?xml version="1.0" encoding="utf-8"?>
<cfdi:Comprobante xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/TimbreFiscalDigital/TimbreFiscalDigital.xsd" xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital" version="3.2" xmlns:cfdi="http://www.sat.gob.mx/cfd/3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
</cfdi:Comprobante>
I'm converting the above file to string successfully and then I'm usign the following code that converts a string to a SqlXML.
cfdiDocumento.CFDIXML = Serializar.XMLToSqlXml(comprobante);
Where cfdiDocumento.CFDIXML is a SqlXml var, Serializar.XMLToSqlXml(comprobante) method receives a string and executes the following code:
public static SqlXml XMLToSqlXml(string xmlString)
{
SqlXml sqlXmlFiltro = null;
if (xmlString != null)
{
StringReader sr = new StringReader(xmlString);
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Auto;
XmlReader reader0 = XmlReader.Create(sr, settings);
sqlXmlFiltro = new SqlXml(reader0);
}
return sqlXmlFiltro;
}
When the code finishes successfully, the file is correct but is removing the xml header
<?xml version="1.0" encoding="utf-8"?>
The question is: How do I preserve the xml header when convierting to SqlXml var?

If you cannot change the type of your SqlXml attribute, you could try converting the SqlXml to xml document to append xml declaration and get the outer xml:
public string SqlXmlToString(SqlXml sqlXml)
{
XmlDocument doc = new XmlDocument();
doc.Load(sqlXml.CreateReader());
// Create XML declaration with your encoding.
XmlDeclaration xmldecl;
xmldecl = doc.CreateXmlDeclaration("1.0", null, null);
xmldecl.Encoding = "UTF-8";
// Add to the document the created declaration
XmlElement root = doc.DocumentElement;
doc.InsertBefore(xmldecl, root);
return doc.OuterXml;
}
Hope this is helpfully

Related

How Can I add XML declaration?

I Have this Xml output from URL XML
using HTTP GET method
How Can I add this XML declaration?
?xml version="1.0" encoding="ISO-8859-1"?>
This is ServiceContract
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Xml,
//BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "{id}")]
XElement GetRecipesByID(string id);
This is implementation,
I convert DataTable To Xml and get from URL
public XElement GetRecipesByID(string id)
{
StringWriter str = new StringWriter();
DataSet dataSet = new DataSet();
dataSet.Tables.Add(Table);
XmlTextWriter xtext = new XmlTextWriter(str);
xtext.Formatting = Formatting.Indented;
xtext.WriteStartDocument();
xtext.WriteStartElement("rss");
xtext.WriteAttributeString("version", "2.0");
xtext.WriteStartElement("channel");
xtext.WriteElementString("title", "GetCard");
xtext.WriteElementString("link", "10.0.0.253");
xtext.WriteElementString("lastBuildDate", " ");
xtext.WriteElementString("generator", "Alikas Feed");
xtext.WriteElementString("error", error);
xtext.WriteElementString("cardid", "RX0016502");
xtext.WriteElementString("name", " ");
xtext.WriteElementString("passport_id", "60001082881");
xtext.WriteElementString("tel", " ");
xtext.WriteEndElement();
xtext.WriteEndDocument();
result = str.ToString();
xtext.Close();
XmlDocument doc = new XmlDocument();
doc.Save(str);
return XElement.Parse(result);
}
When I save this xml in file there is xml declaration but when I try to get this xml from URL xml declaration doesn't show.
I need to show this declaration from URL.
Thank you
WriteStartDocument should already be adding the XML declaration. It uses the Encoding specified by your TextWriter.
You're using a StringWriter which will always report UTF-16 as .NET Strings are in UTF-16. To get ISO-8859-1, you'll need to construct a StreamWriter or some other TextWriter with an explicit encoding.
Have you considered creating an XDocument directly? No need to use XmlWriter in that case.
Try following :
string header = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><rss version=\"2.0\"/>";
XDocument doc = XDocument.Parse(header);
XElement rss = doc.Root;
Boolean error = false;
rss.Add(new XElement("channel", new object[] {
new XElement("title", "GetCard"),
new XElement("link", "10.0.0.253"),
new XElement("lastBuildDate", " "),
new XElement("generator", "Alikas Feed"),
new XElement("error", error),
new XElement("cardid", "RX0016502"),
new XElement("name"),
new XElement("passport_id", "60001082881"),
new XElement("tel")
}));
doc.Save(#"c:\temp\test.xml");
There is an special method for this:
var xmlDoc = new XmlDocument();
xmlDoc.CreateXmlDeclaration("1.0", "ISO-8859-1", null);
xmlDoc.Save(str);
Note from the msdn on encoding parameter: This is the encoding that is used when you save the XmlDocument to a file or a stream; therefore, it must be set to a string supported by the Encoding class, otherwise Save fails.
This seems to work for me
XDocument xel = XDocument.Parse( "<root><el>123</el></root>" );
xel.Declaration = new XDeclaration( "1.0","UTF-8","true" );
xel.Save( #"c:\temp.xml" );

how to add processing instruction in xml using XmlDocument

I am writing a XML using XmlDocument, I need a element or attribute like shown below
The element or attribute required is <?Validversion="1" ?>
how to create using xmldocument or xmlwriter.
// to create <?Validversion="1" ?>
XmlDocument aDoc = new XmlDocument();
aDoc.CreateXmlDeclaration("1.0", "utf-16", null);
XmlCDataSection aDataSec =aDoc.CreateCDataSection("?Version = 2");
aDoc.AppendChild(aDataSec);
aDoc.Save("c:\\vector.xml");
You are looking for XmlDocument.CreateProcessingInstruction and not CDATA section:
var document = new XmlDocument();
document.AppendChild(document.CreateXmlDeclaration("1.0", "utf-16", null));
var piNode = document.CreateProcessingInstruction("Version", "=\"2\"");
document.AppendChild(pi);
Side note: don't forget to AppendChild newly created node.

Writing in xml does not keep the formatting?

I have this string :
<test>I am a test</test>
But when I write it in my xml file, and open it, I have this :
<test>I am a test</test>
I don't know how to use the good formatting. I tried HttpUtility.HtmlDecode, but it does not solve my problem.
Do you have an idea on this ?
Edit : Sorry for not having posted my code before, I thought my problem was really really trivial. Here is a sample I just wrote that resumes the situation (I'm not at work anymore so I don't have the original code) :
XmlDocument xmlDoc = new XmlDocument();
doc.LoadXml("<root>" +
"<test>I am a test</test>" +
"</root>");
string content = xmlDoc.DocumentElement.FirstChild.InnerXml;
XDocument saveFile = new XDocument();
saveFile = new XDocument(new XElement("settings", content));
saveFile.Save("myFile.xml");
I just want my xml file content looks like my original string,
so in my case the file would normally contain :
<settings>
<root>
<test>I am a test</test>
</root>
</settings>
Right ? But instead, I have something like :
<settings><root><test>I am a test</test></root>
</settings>
You can do something along the lines of Converting XDocument to XmlDocument and vice versa to convert the root element of your XmlDocument to an XElement and then add it to your XDocument:
public static class XmlDocumentExtensions
{
public static XElement ToXElement(this XmlDocument xmlDocument)
{
if (xmlDocument == null)
throw new ArgumentNullException("xmlDocument");
if (xmlDocument.DocumentElement == null)
return null;
using (var nodeReader = new XmlNodeReader(xmlDocument.DocumentElement))
{
return XElement.Load(nodeReader);
}
}
}
And then use as follows:
// Get legacy XmlDocument
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("<root>" +
"<test>I am a test</test>" +
"</root>");
// Add its root element to the XDocument
XDocument saveFile = new XDocument(
new XElement("settings", xmlDoc.ToXElement()));
// Save
Debug.WriteLine(saveFile.ToString());
And the output is:
<settings>
<root>
<test>I am a test</test>
</root>
</settings>
Note this avoids the overhead of converting the XmlDocument to an XML string and re-parsing it from scratch.

How to add comment to end of XmlDocument in C# when returned from ASMX Webservice

I have the following class;
[XmlRoot("Customer")]
public class MyClass
{
[XmlElement("CustId")]
public int Id {get;set;}
[XmlElement("CustName")]
public string Name {get;set;}
}
I then use the following function serialise the class object to Xml
public static XmlDocument SerializeObjectToXML(object obj, string sElementName)
{
XmlSerializer serializer =
new XmlSerializer(obj.GetType(), new XmlRootAttribute("Response"));
using (MemoryStream ms = new MemoryStream())
{
XmlDocument xmlDoc = new XmlDocument();
serializer.Serialize(ms, obj);
ms.Position = 0;
xmlDoc.Load(ms);
}
}
My current output to XML is like;
<Response>
<CustId></CustId>
<CustName></CustName>
</Response>
However I'd like to add a comment like
<Response>
<CustId></CustId>
<CustName></CustName>
</Response>
<!-- Sample Comment Here -->
How can I achieve this ? I tried the following;
XmlComment xmlComment;
xmlComment = xmlDoc.CreateComment("Sample XML document");
XmlElement root = xmlDoc.DocumentElement;
xmlDoc.InsertAfter(xmlComment, root);
But, when I try to read the Xml using this kind of WebClient call
oClient.UploadString("http://www.myurl.com/", "POST", "");
I can see the Xml elements, but not the comment.
UPDATE
I checked, and even if I call the webservice (ASMX) directly via a browser, the comment tag is NOT returned when using the browser developer Tools.
It would appear that the ASMX webservice is not returning the comment tag...?

Make xml more readable

Is there any way to take an xml string in .net and make it easyer to read?
what i mean is can i convert this:
<element1><element2>some data</element2></element1>
to this:
<element1>
<element2>
some data
</element2>
</element1>
is there any built in class for this? as sql server 2005 seems to remove all formatting on xml to save space or some thing...
If you're using .NET 3.5, you can load it as an XDocument and then just call ToString() which will indent it appropriately. For example:
using System;
using System.Xml.Linq;
public class Test
{
static void Main()
{
string xml = "<element1><element2>some data</element2></element1>";
XDocument doc = XDocument.Parse(xml);
xml = doc.ToString();
Console.WriteLine(xml);
}
}
Result:
<element1>
<element2>some data</element2>
</element1>
If you're writing it to a file or other stream, then XDocument.Save will (by default) indent it too.
(I believe XElement has all the same features, if you don't really need an XDocument.)
How do you save / write the XML back to a file ?
You can create an XmlWriter and pass it an XmlWriterSettings instance, where you set the Indent property to true:
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter writer = XmlWriter.Create (outputStream, settings);
You can load the string into an XDocument object and save it to a string again:
XDocument doc = XDocument.Load(new StringReader(xmlString));
StringWriter writer = new StringWriter();
doc.Save(writer);
string readable = writer.ToString();
That will give you the xml formatted this way:
<?xml version="1.0" encoding="utf-16"?>
<element1>
<element2>some data</element2>
</element1>
Have a look at
XmlWriterSettings
http://msdn.microsoft.com/en-us/library/system.xml.xmlwritersettings.aspx
you can define Indent and IndentChars
First of all, you have tagged C# and VB.NET both. So my answer will be for both of them.
You can define function which get XML string as a parameter in type of String.
Let's say;
You created a function as :
[VB]
Private Function PrettyXML(XMLString As String) As String
Dim sw As New StringWriter()
Dim xw As New XMLWriter(sw)
xw.Formatiing = Formatting.Indented
xw.Indentation = 4
Dim doc As New XMLDocument
doc.LoadXML(XMLString)
doc.Save(xw)
Return sw.ToString()
End Function
Then you can simpyl call this function as:
Dim myXML As String = "<element1><element2>some data</element2></element1>"
Dim myPrettyXML As String
myPrettyXML = PrettyXML(myPrettyXML)
[C#]
Private String PrettyXML(string XMLString)
{
StringWriter sw = new StringWriter();
XMLTextWriter xw = new XmlTextWriter(sw);
xw.Formatiing = Formatting.Indented;
xw.Indentation = 4;
XmlDocument doc = new XmlDocument();
doc.Save(xm);
return sw.ToString();
}
Then you can simply call this function as:
string myXML = "<element1><element2>some data</element2></element1>";
string myPrettyXML = "";
myPrettyXML = PrettyXML(myPrettyXML);
NOTE: I have not tried C# version, but it should work.
Hope this helps..

Categories

Resources