I'm trying to insert a xml file that I read from a stream into a column of type xml in mssql server
like this:
//read file from stream
var reader = new StreamReader(request.InputStream, Encoding.UTF8);
var string = reader.ReadToEnd();
//convert to xmldoc
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(string);
//Try to inser it into the table using the xmlDoc
using (SqlConnection con = new SqlConnection(_connectionString))
{
con.Open();
using (SqlCommand cmd = new SqlCommand(
#"INSERT INTO [XMLTable] (XmlData) VALUES(#XmlData);", con))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#XmlData", xmlDoc.InnerXml);
cmd.ExecuteScalar();
}
}
//Sample xml :
<?xml version="1.0" encoding="utf-8"?>
<ChangeSSNR version="1.0" xmlns="http://schemas.testschema.com/ChangeSSNR/1.0/">
<Header version="1.0">
<From>someone</From>
<To>someoneelse</To>
<TimeStamp>1900-01-01T01:01:01+01:00</TimeStamp>
<ppnSchema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
</Header>
<ChangeSSNRid id="4294967295">
<SSNRChange>
<NewSSNR>09834098098</NewSSNR>
<OldSSNR>9879879827345</OldSSNR>
</SSNRChange>
</ChangeSSNRid>
<ChangeSSNRid id="42949367295">
<SSNRChange>
<NewSSNR>098340980983</NewSSNR>
<OldSSNR>98798798273453</OldSSNR>
</SSNRChange>
</ChangeSSNRid>
</ChangeSSNR>
Getting an exception : XML parsing: line 1, character 38, unable to switch the encoding
Kind Regards
/Rudy
The XML file shouldn't have any leading spaces on the first line:
XML
<?xml version="1.0" encoding="utf-8"?>
<ChangeSSNR version="1.0" xmlns="http://schemas.testschema.com/ChangeSSNR/1.0/">
<Header version="1.0">
<From>someone</From>
<To>someoneelse</To>
<TimeStamp>1900-01-01T01:01:01+01:00</TimeStamp>
<ppnSchema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:nil="true"/>
</Header>
<ChangeSSNRid id="4294967295">
<SSNRChange>
<NewSSNR>09834098098</NewSSNR>
<OldSSNR>9879879827345</OldSSNR>
</SSNRChange>
</ChangeSSNRid>
<ChangeSSNRid id="42949367295">
<SSNRChange>
<NewSSNR>098340980983</NewSSNR>
<OldSSNR>98798798273453</OldSSNR>
</SSNRChange>
</ChangeSSNRid>
</ChangeSSNR>
It is better to use LINQ to XML while dealing with XML. It is available in the .Net Framework since 2007.
c#
...
XDocument xdoc = XDocument.Parse(string);
...
cmd.Parameters.AddWithValue("#XmlData", xdoc.ToString());
Related
I have an XML file with some data on it..for example
<?xml version="1.0" encoding="utf-8"?>
<CreateAndSendMessageRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.communisis.com/lv">
<CompositionRequest>
<Metadata xmlns="http://lv.com/gi/si/common/CommonTypes">
<PolicyReference>250028766505DN</PolicyReference>
<AccountReference>Test1234</AccountReference>
<QuoteReference>Test3214</QuoteReference>
<OutboundTransactionID>string</OutboundTransactionID>
</Metadata>
Now i want to replace POLICY REFERENCE value with some dummy data. I am able to do that but now i have to save it as a new file with a different file name..
How can i achieve that..
For reference i am giving my code.
XmlDocument doc = new XmlDocument();
doc.Load(filepath);
XmlNodeList node = doc.GetElementsByTagName("PolicyReference");
var item =node.Item(0);
string value = item.FirstChild.Value;
string nevalue = value.Replace(value, "Test123");
doc.DocumentElement.;
doc.Save(#"C:\Test\file.xml");
The xml wasn't valid.
Anyway, this is how to make it work:
Xml file:
<?xml version="1.0" encoding="UTF-8"?>
<CreateAndSendMessageRequest>
<CompositionRequest>
<Metadata xmlns="http://lv.com/gi/si/common/CommonTypes">
<PolicyReference>250028766505DN</PolicyReference>
<AccountReference>Test1234</AccountReference>
<QuoteReference>Test3214</QuoteReference>
<OutboundTransactionID>string</OutboundTransactionID>
</Metadata>
</CompositionRequest>
</CreateAndSendMessageRequest>
Code:
XmlDocument doc = new XmlDocument();
doc.Load("bho.xml");
XmlNodeList node = doc.GetElementsByTagName("PolicyReference");
node[0].InnerText = "Test123";
doc.Save("file.xml");
Result xml:
<?xml version="1.0" encoding="UTF-8"?>
<CreateAndSendMessageRequest>
<CompositionRequest>
<Metadata xmlns="http://lv.com/gi/si/common/CommonTypes">
<PolicyReference>Test123</PolicyReference>
<AccountReference>Test1234</AccountReference>
<QuoteReference>Test3214</QuoteReference>
<OutboundTransactionID>string</OutboundTransactionID>
</Metadata>
</CompositionRequest>
</CreateAndSendMessageRequest>
Hope it helps you ^^
The code below works in C#, no error, no exception. The problem is that the numconfig.xml file won't change after running the code.
C# code:
XmlNodeList xm = new XmlManager(System.Web.HttpContext.Current.Server.MapPath("~/Xml/numconfig.xml")).ReadAllChild(#"//number");
xm[0].SelectSingleNode("abc[#name='upper']").Attributes["value"].Value = "201";
Xml file:
<?xml version="1.0" encoding="utf-8" ?>
<number>
<aaa>
<abc value="200" text="xxxx" name="upper"/>
</aaa>
</number>
How are you trying to commit the changes back to the file? Your code does not show an example eg
using (var streamWriter = new StreamWriter(location))
{
foreach (XmlNode xmlNode in xm)
{
streamWriter.WriteLine(xmlNode.OuterXml);
}
}
The Application serializes a List to xml:
<?xml version="1.0"?>
<Tools xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Tool>
<Name>test1</Name>
<Path>C:\Program Files\FreePDF_XP\fpmailer.exe</Path>
</Tool>
<Tool>
<Name>test2</Name>
<Path>C:\Program Files\FreePDF_XP\fpassist.exe</Path>
</Tool>
<Tool>
<Name>test3</Name>
<Path>C:\Program Files\FreePDF_XP\ShellMail.exe</Path>
</Tool>
</Tools>
If I'm don't on the wrong way I must create new Objects and add them to a list:
Tool tool = new Tool();
XmlSerializer deserializer = new XmlSerializer(typeof(List<Tool>));
using (var reader = new StreamReader(#Start.userConfigurePath + "\\config.xml"))
{
tool = (Tool)deserializer.Deserialize(reader);
reader.Close();
}
toolList.Add(tool);
}
In the result there isn't a Object in the List. How can I deserialize the serialized objects in the xml in a List? Could it be that there is something wrong at the code for derisalization?
Edit:
Something seems to be wrong with my xml declaration (XML File Error 2,2). That I don't understand because i create the xml document on this way:
XmlDocument toolConfig = new XmlDocument();
XmlNode myRoot;
myRoot = toolConfig.CreateElement("Tool");
toolConfig.AppendChild(myRoot);
It should be
toolList = (List<Tool>)deserializer.Deserialize(reader);
I have an xml file that is styled with xslt to produce html email template. I get values from users dynamically and replace xml elements text with the values received. How can i get that xml file and send as html email body in c#?
My Xml Looks Like This
<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="EmailTemplateStyleForHTML.xslt"?>
<EmailTemplate>
<subject>Information from xyz</subject>
<displayName>abcd</displayName>
<Message1>
Thanks you for registering to xyz.
</Message1>
<Copyright>Copyright xyz</Copyright>
</EmailTemplate>
I am using LINQ to set the values to the xml.
Note: I know how to get and set the values from xml but what i want is to grab the whole xml file in to the email body.
If you think there is a better approach for this i would love to hear that. I would really appreciate your help.
Edited after Reply:
The xsl transformation part :
TextReader tr1 = new StringReader(#"EMailTemplateHtml.xml");
var tr11 = new XmlTextReader(tr1);
var xPathDocument = new XPathDocument(tr11);
//read XSLT
TextReader tr2 = new StringReader(#"EmailTemplateStyleForHTML.xslt");
var tr22 = new XmlTextReader(tr2);
var xslt = new XslTransform();
xslt.Load(tr22);
var sb = new StringBuilder();
TextWriter tw = new StringWriter(sb);
xslt.Transform(xPathDocument, null, tw);
emailBody = sb.ToString();
I am doing the transformation as you said(#Roy Ashbrook) am i missing anything here?
I believe you will need to actually perform the XSL transform in memory, not reference it in the XML itself. It's possible you could store the XSL in a remote location and reference it that way, but I wouldn't
so:
inject your values into your xml string
transform your xml using your xsl
make that your html message body
Here is some code. Mostly borrowed from/inspired by:
How to transform XML as a string w/o using files in .NET? and Sending E-mail using C#.
void Main()
{
SendHtmlBody(GetHtmlBody());
}
void SendHtmlBody(string HtmlBody){
using(SmtpClient c = new SmtpClient())
{
//set smtp options here
using(MailMessage msg = new MailMessage("from#replace.me","to#replace.me"))
{
msg.Subject = "Testing Bulk mail application";
msg.Body = HtmlBody;
msg.IsBodyHtml = true;
//c.Send(msg);
}
}
}
string GetHtmlBody(){
string xmlInput = #"<?xml version=""1.0"" encoding=""utf-8"" ?>
<EmailTemplate>
<subject>Information from xyz</subject>
<displayName>abcd</displayName>
<Message1>
Thanks you for registering to xyz.
</Message1>
<Copyright>Copyright xyz</Copyright>
</EmailTemplate>";
string xslInput = #"<?xml version=""1.0"" encoding=""ISO-8859-1""?>
<xsl:stylesheet version=""1.0""
xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
<xsl:template match=""/"">
<html>
<body>
<h5><xsl:value-of select=""EmailTemplate/subject""/></h5>
<h5><xsl:value-of select=""EmailTemplate/displayName""/></h5>
</body>
</html>
</xsl:template>
</xsl:stylesheet>";
using (StringReader srt = new StringReader(xslInput)) // xslInput is a string that contains xsl
using (StringReader sri = new StringReader(xmlInput)) // xmlInput is a string that contains xml
{
using (XmlReader xrt = XmlReader.Create(srt))
using (XmlReader xri = XmlReader.Create(sri))
{
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xrt);
using (StringWriter sw = new StringWriter())
using (XmlWriter xwo = XmlWriter.Create(sw, xslt.OutputSettings)) // use OutputSettings of xsl, so it can be output as HTML
{
xslt.Transform(xri, xwo);
return sw.ToString();
}
}
}
}
I have successfully been able to transform a simple xml file with data to another xml file (excel template) using a xsl template, this is what my xsl file looks like:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" standalone="yes"/>
<xsl:template match="/">
<xsl:processing-instruction name="mso-application">
<xsl:text>progid="Excel.Sheet"</xsl:text>
</xsl:processing-instruction>
...(stuff here)...
</xsl:template>
</xsl:stylesheet>
The resulting xml file is written out correctly BUT with the exception of including
<?xml version="1.0"?>
at the top of the file. How can I get it to appear at the top?
Currently my resulting xml file starts with:
<?mso-application progid="Excel.Sheet"?>
...(rest of file)...
But what I need it to do is:
<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
.(rest of file)...
I'm doing this transform through a windows form with the following code:
XPathDocument myXPathDoc = new XPathDocument(xmlfile);
XslCompiledTransform myXslTrans = new XslCompiledTransform();
myXslTrans.Load(xslfile);
XmlTextWriter myWriter = new XmlTextWriter(xmlexcelfile, null);
myWriter.Formatting = Formatting.Indented;
myWriter.Namespaces = true;
myXslTrans.Transform(myXPathDoc, null, myWriter);
myWriter.Close();
I've tried playing around with the xsl:output standalone="yes/no", as well as omit-xml-declaration="no". I've also tried (in the C#) code adding myWriter.WriteStartDocument(); before transforming but that was not allowed. I have tried searching online for this as well and keep coming back to the standalone="yes" but that isn't working. Is there something I am missing here? Oh and in case you are wondering why I need to have the
<?xml version="1.0"?>
at the top of the resulting file, it's because when opening the xml file with excel, excel doesn't recognize it correctly but if it is included then excel opens it correctly...
You can do this
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" />
or something similar to this using XmlWriterSettings
Edit: Added more code. Previous was missing some parts
XmlWriterSettings writerSettings = null;
XsltArgumentList transformationArguments = null;
XslCompiledTransform transformer = null;
MemoryStream memoryStream = null;
XPathDocument xPathDocument = null;
StringBuilder sb = null;
XmlWriter writer = null;
XmlDocument resultXml = null;
try
{
writerSettings = new XmlWriterSettings();
writerSettings.OmitXmlDeclaration = false; // This does it
writerSettings.Indent = true;
transformationArguments = new XsltArgumentList();
transformer = new XslCompiledTransform();
memoryStream = new MemoryStream(System.Text.Encoding.Default.GetBytes(xml.OuterXml));
xPathDocument = new XPathDocument(new StreamReader(memoryStream));
sb = new StringBuilder();
// give the settings to the writer here
writer = XmlWriter.Create(sb, writerSettings);
// this is not mandatory, obviously, just passing parameters to my xslt file
foreach (KeyValuePair<string, object> parameter in parameters)
{
transformationArguments.AddParam(parameter.Key, string.Empty, parameter.Value);
}
using (Stream strm = Assembly.GetExecutingAssembly().GetManifestResourceStream("Lib.XSLTFile1.xslt"))
using (XmlReader reader = XmlReader.Create(strm))
{
transformer.Load(reader);
transformer.Transform(xPathDocument, transformationArguments, writer);
}
resultXml = new XmlDocument();
resultXml.LoadXml(sb.ToString());
// for testing only
File.AppendAllText(#"Your path goes here\result.xml", resultXml.OuterXml);
}
catch (Exception)
{
throw;
}
This is how I do it, but this code is specifically written to create an instance of a XmlDocument. I'm sure you can adapt to your needs.