I'm working on an app an i'm saving the data in an XML format but i'm having issues with getting the format correct.
the output looks like this
<GasInfoEntries>
<Gallons>123</Gallons>
<Price>456</Price>
</GasInfoEntries><GasInfoEntries>
<Gallons>123</Gallons>
<Price>456</Price>
</GasInfoEntries>
im using this to write it
List<GasInfoEntries> data = new List<GasInfoEntries>();
data.Add(new GasInfoEntries() { Gallons = TxtBoxGas.Text, Price = TxtBoxPrice.Text });
xmlWriter.WriteStartDocument();
xmlWriter.WriteStartElement("GasInfoEntries");
xmlWriter.WriteStartElement("Gallons", "");
xmlWriter.WriteString(TxtBoxGas.Text);
xmlWriter.WriteEndElement();
xmlWriter.WriteStartElement("Price", "");
xmlWriter.WriteString(TxtBoxPrice.Text);
xmlWriter.WriteEndElement();
xmlWriter.WriteEndDocument();
xmlWriter.Flush();
//do i need?
xmlWriter.Close();
i'm getting this error
- $exception
{System.InvalidOperationException: There is an error in XML document (1, 2). ---> System.InvalidOperationException: <GasInfoEntries xmlns=''> was not expected.
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderList1.Read3_ArrayOfGasInfoEntries()
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, Object events)
at System.Xml.Serialization.XmlSerializer.Deserialize(Stream stream)
at LP_Buddy.MainPage.btnShow_Click(Object sender, RoutedEventArgs e)}
System.Exception {System.InvalidOperationException}
any ideas?
thanks
You are missing the root XML element which is required in XML document. Just add it like this:
<GasRoot>
<GasInfoEntries>
<Gallons>123</Gallons>
<Price>456</Price>
</GasInfoEntries>
<GasInfoEntries>
<Gallons>123</Gallons>
<Price>456</Price>
</GasInfoEntries>
</GasRoot>
Related
XmlTypeMapping myTypeMapping = new SoapReflectionImporter().ImportTypeMapping(typeof(AddressValidationRequest));
XmlSerializer serializer = new XmlSerializer(myTypeMapping);
TextWriter writer = new StreamWriter(filename);
serializer.Serialize(writer, request);
writer.Close();
I am trying to serialize a class into XML (SOAP). I keep receiving the error message below. Does anyone know why this might be happening?
System.InvalidOperationException: 'There was an error generating the XML document.'
InvalidOperationException: Token StartElement in state Epilog would result in an invalid XML document.
System.InvalidOperationException
HResult=0x80131509
Message=There was an error generating the XML document.
Source=System.Private.Xml
StackTrace:
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o, XmlSerializerNamespaces namespaces)
at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o)
This exception was originally thrown at this call stack:
System.Xml.XmlTextWriter.AutoComplete(System.Xml.XmlTextWriter.Token)
System.Xml.XmlTextWriter.WriteStartElement(string, string, string)
System.Xml.Serialization.XmlSerializationWriter.WriteStartElement(string, string, object, bool, System.Xml.Serialization.XmlSerializerNamespaces)
System.Xml.Serialization.XmlSerializationWriter.WriteArray(string, string, object, System.Type)
System.Xml.Serialization.XmlSerializationWriter.WriteReferencedElement(string, string, object, System.Type)
System.Xml.Serialization.XmlSerializationWriter.WriteReferencedElements()
System.Xml.Serialization.ReflectionXmlSerializationWriter.GenerateTypeElement(object, System.Xml.Serialization.XmlTypeMapping)
System.Xml.Serialization.ReflectionXmlSerializationWriter.WriteObject(object)
System.Xml.Serialization.XmlSerializer.SerializeUsingReflection(System.Xml.XmlWriter, object, System.Xml.Serialization.XmlSerializerNamespaces, string, string)
System.Xml.Serialization.XmlSerializer.Serialize(System.Xml.XmlWriter, object, System.Xml.Serialization.XmlSerializerNamespaces, string, string)
Inner Exception 1:
InvalidOperationException: Token StartElement in state Epilog would result in an invalid XML document.
Use XmlTextWriter instead of TextWriter and do a writer.WriteStartElement("wrapper"):
XmlTypeMapping myTypeMapping = new SoapReflectionImporter().ImportTypeMapping(typeof(AddressValidationRequest));
XmlSerializer serializer = new XmlSerializer(myTypeMapping);
XmlTextWriter writer = new XmlTextWriter(filename, System.Text.Encoding.UTF8);
writer.Formatting = System.Xml.Formatting.Indented;
writer.WriteStartElement("wrapper");
serializer.Serialize(writer, request);
writer.WriteEndElement();
writer.Close();
Reference:
https://learn.microsoft.com/en-us/dotnet/api/system.xml.serialization.soapreflectionimporter?view=net-6.0#examples
I'm trying to write an XML file for OpenClinica, a clinical trial platform who uses CDISC ODM XML representation.
My problem is when I try to write the very first element of the XML with an XmlWriter, I have this exception :
An exception of type 'System.Xml.XmlException' occurred in System.Xml.dll but
was not handled in user code
Additional information: The prefix '' cannot be redefined from '' to
'http://www.cdisc.org/ns/odm/v1.3' within the same start element tag.
Here's what I want in my file :
<ODM xmlns="http://www.cdisc.org/ns/odm/v1.3"
xmlns:OpenClinica="http://www.openclinica.org/ns/odm_ext_v130/v3.1"
xmlns:OpenClinicaRules="http://www.openclinica.org/ns/rules/v3.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
FileOID="testD20161121140900+0000"
Description="test"
CreationDateTime="2016-11-21T14:09:00+00:00"
FileType="Snapshot"
ODMVersion="1.3"
xsi:schemaLocation="http://www.cdisc.org/ns/odm/v1.3 OpenClinica-ODM1-3-0-OC2-0.xsd">
And here's my code :
StringWriter swriter = new StringWriter();
XmlWriter writer = XmlWriter.Create(swriter);
writer.WriteStartElement("ODM");
writer.WriteAttributeString("xmlns", "http://www.cdisc.org/ns/odm/v1.3");
writer.WriteAttributeString("xmlns", "OpenClinica", null, "http://www.openclinica.org/ns/odm_ext_v130/v3.1");
writer.WriteAttributeString("xmlns","OpenClinicaRules",null, "http://www.openclinica.org/ns/rules/v3.1");
writer.WriteEndElement();
writer.Close();
return swriter.ToString();
If I try to write only the "xmlns:OpenClinica" and the "xmlns:OpenClinicaRules" attributes, it's going well but the problem occurs when I try to write the xmlns attribute.
What could be the problem here ?
Try the following:
writer.WriteStartElement("","ODM","http://www.cdisc.org/ns/odm/v1.3");
I have a lot of XML files with the same structure. Many of them working OK, but for some XmlSerializer gives me an error but when I put the document in xml validator - it says that document is correct.
Deserialization code:
var document = serializer.Deserialize(File.OpenRead(file));
Error:
System.InvalidOperationException: There is an error in XML document (504, 8). ---> System.Xml.XmlException: Unexpected node type Element. ReadElementString method can only be called on elements with simple or empty content. Line 504, position 8.
at System.Xml.XmlReader.ReadElementString()
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderPatentdocument.Read33_Claimtext(Boolean isNullable, Boolean checkType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderPatentdocument.Read34_Claim(Boolean isNullable, Boolean checkType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderPatentdocument.Read35_Claims(Boolean isNullable, Boolean checkType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderPatentdocument.Read43_Patentdocument(Boolean isNullable, Boolean checkType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderPatentdocument.Read44_patentdocument()
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
at System.Xml.Serialization.XmlSerializer.Deserialize(Stream stream)
The part of the document where it gives the error:
<text>12. Führungsschiene nach einem der Ansprüche 2 bis 11, dadurch gekennzeichnet, daß in den beiden Nutwänden (<b>11<i>a</i>, 11</b><i>a′)</i> einander gegenüberliegende Bohrungen (<b>14</b><i>a</i>, <b>14</b><i>a</i>′) vorgesehen sind, von denen die eine Bohrung (<b>14</b><i>a</i>′) durch das Einsatzteil (<b>15</b><i>a)</i> verschlossen ist.</text>
I suppose it is because of inline html tags inside because it complains about this line on position of i tag
<b>11<i>a</i>, 11</b>
But for example this xml is correct according to XmlSerializer and it is possible to deserialize it:
<text>9. Führungsschiene nach Anspruch 8, dadurch gekennzeichnet, daß der Ansatz (<b>20</b>) die Zuführfläche (<b>25</b>) aufweist.</text>
So my question why xml validator says that the document is valid and XmlSerializer cannot deserialize it? Is it possible to have a workaround without changing the document?
You're right when you point at the inner HTML tags.
Your XML is not valid because you have tags inside a simple (text) element. XmlSerializer doesn't understand and throws an error.
If you have generated the XML files, you have to escape the data inside the simple elements beforehand :
with HTML Encode
Or by encapsulating it in a CDATA tag (<![CDATA[...]]>)
Try serializing the instance that is causing you problems. Then you can compare the output of the serialization with the contents of the file you are attempting to deserialize. The difference between the two XML strings will show you where the problem is.
Here is a quick function to serialize an instance of a class to XML:
public static string Serialize<T>(T entity)
{
if (entity == null)
return String.Empty;
try
{
XmlSerializer XS = new XmlSerializer(typeof(T));
System.IO.StringWriter SW = new System.IO.StringWriter();
XS.Serialize(SW, entity);
return SW.ToString();
}
catch (Exception e)
{
Logging.Log(Severity.Error, "Unable to serialize entity", e);
return String.Empty;
}
}
If you haven't tried it yet, I would suggest the software BeyondCompare to easily see the difference between the two files.
Suppose we have the following class:
public class Foo
{
//[XmlIgnore]
public string Text { get; set; }
}
And xml of the following form:
<Foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<text>12. Führungsschiene nach einem der Ansprüche 2 bis 11, dadurch gekennzeichnet, daß in den beiden Nutwänden (<b>11<i>a</i>, 11</b><i>a′)</i> einander gegenüberliegende Bohrungen (<b>14</b><i>a</i>, <b>14</b><i>a</i>′) vorgesehen sind, von denen die eine Bohrung (<b>14</b><i>a</i>′) durch das Einsatzteil (<b>15</b><i>a)</i> verschlossen ist.</text>
</Foo>
Then we can deserialize the data as follows.
var xs = new XmlSerializer(typeof(Foo));
xs.UnknownElement += Xs_UnknownElement;
Foo foo;
using (var fs = new FileStream("test.txt", FileMode.Open))
{
foo = (Foo)xs.Deserialize(fs);
}
Subscribe XmlSerializer to UnknownElement event.
In the event handler manually set our property to the data.
private static void Xs_UnknownElement(object sender, XmlElementEventArgs e)
{
var foo = (Foo)e.ObjectBeingDeserialized;
foo.Text = e.Element.InnerXml;
}
Please note that the property name should not match the xml node name (case sensitive). Only in this case the event is triggered. If the names match, use the XmlIgnore attribute.
I appreciate your help.
I have created a web service to receive an XML file, so I followed the below approach then I published it and it worked fine for me :
....
XmlDocument xmldoc = new XmlDocument();
try
{
if (HttpContext.Current.Request.InputStream != null)
{
StreamReader stream = new StreamReader(HttpContext.Current.Request.InputStream);
string xmls = stream.ReadToEnd();
xmldoc.LoadXml(xmls);
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
}
}
catch (Exception ex)
{
logger.Log(NLog.LogLevel.Error, ex.Message + ex.StackTrace);
}
...
knowing that my XML structure is:
<reports uis="5521452542">
<attribute1>val1</attribute1>
...
</reports>
but after testing by some friends, that called my web service from the Lunix platform I received in the Log file error the below message error; knowing that their XML file is validated.
Just to let you know; that their XML file did not contains the declaration of:
<?xml version="1.0" encoding="UTF-8"?>
Can this provide the error or NOT ?
2014-04-03 03:56:53.7408|Error|Root element is missing.
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
at System.Xml.XmlDocument.Load(XmlReader reader)
at System.Xml.XmlDocument.LoadXml(String xml)
at WebService.Service1.GetInfoService() in
D:\yassine\Mobily\Log\WebService\WebService\WebService\Service1.asmx.cs:line 56
2014-04-03 03:56:53.8032|Error|Root element is missing. at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.Linq.XDocument.Load(XmlReader reader, LoadOptions options)
at System.Xml.Linq.XDocument.Parse(String text, LoadOptions options)
at WebService.Service1.GetInfoService() in
D:\yassine\Mobily\Log\WebService\WebService\WebService\Service1.asmx.cs:line 71
Can you please help me to find the exact error please ?
Thank you
The exception is saying exactly whats wrong, you are receiving an invalid xml that has no root element. Ask your friends to send you the raw xml by mail so you could see what they're sending you.
You can you Altova XmlSpy to verify that the xml is valid.
A very basic but valid xml should be:
<root>
<child></child
</root>
For reasons I wont' go into here, I can't use the object type as a parameter into my webapi controller. Therefore, I need to figure out a way to deserialize the xml object into my c# object using XmlDocument, or something similar.
Here's what I have so far:
public void Post(HttpRequestMessage request)
{
var xmlDoc = new XmlDocument();
xmlDoc.Load(request.Content.ReadAsStreamAsync().Result);
using (XmlReader xmlReader = new XmlNodeReader(xmlDoc))
{
Object obj = new XmlSerializer(typeof(myObject)).Deserialize(xmlReader);
myObject scp = (myObject)obj;
}
}
unfortunately that's throwing errors. Can anyone provide some suggestion as to how I can deserialize my xml into my object?
tia
Edit: here's the xml I'm trying to deserialize:
<Student>
<studentid>1234</studentid>
<command>post</command>
<posttype>charge</posttype>
<transaction_description>This is a test post to the web api</transaction_description>
<payment_type>CC</payment_type>
<term_code>2013SPRING</term_code>
<amount>432.75</amount>
</Student>
and here's the error I'm getting:
System.InvalidOperationException: was not expected.
Generated: Wed, 19 Mar 2014 20:18:58 GMT
System.InvalidOperationException: There is an error in XML document
(1, 2). ---> System.InvalidOperationException: was
not expected. at
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderStudentChargePost.Read3_StudentChargePost()
--- End of inner exception stack trace --- at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader
xmlReader, String encodingStyle, XmlDeserializationEvents events)
at System.Xml.Serialization.XmlSerializer.Deserialize(Stream stream)
at
CashNetSSO.Controllers.API.StudentInformationPostController.Post(HttpRequestMessage
request) in
C:\Projects\CashNetSSO\Development\CashNetSSO\CashNetSSO\Controllers\API\StudentInformationPostController.cs:line
23 at lambda_method(Closure , Object , Object[] ) at
System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c_DisplayClassf.b_9(Object
instance, Object[] methodParameters) at
System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object
instance, Object[] arguments) at
System.Web.Http.Controllers.ReflectedHttpActionDescriptor.<>c_DisplayClass5.b_4()
at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1
func, CancellationToken cancellationToken)
If you are already reading the content as a stream you can do the following:
myObject scp = null;
XmlSerializer serializer = new XmlSerializer(typeof(myObject);
using (Stream stream = request.Content.ReadAsStreamAsync().Result)
{
scp = serializer.Deserialize(stream);
}
Edit:
The reason you are getting the error is because the XmlSerializer is expecting an xml declaration tag. If your xml does not contain this you can define the root attribute like below:
XmlSerializer serializer = new XmlSerializer(typeof(myObject), new XmlRootAttribute("Student"));