In my application, i have serialized c# object to xml and passed xml to API to generate data and got the reponse xml in return as expected as below,
<?xml version="1.0" encoding="utf-8"?>
<SaveLockResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.easy2access.no/webservice/types">
<Data xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" i:nil="true"/>
<Header>New lock was created</Header>
<Message>A lock with serialnumber [23-215-038-028476] was successfully created for customer [28242].</Message>
<Status>Success</Status>
<Lock xmlns:d2p1="http://schemas.datacontract.org/2004/07/Easy2Access.Engine.Engine.Types">
<d2p1:CustomerNumber>28242</d2p1:CustomerNumber>
<d2p1:Description>String</d2p1:Description>
<d2p1:G3LockId>0</d2p1:G3LockId>
<d2p1:LockId>28158</d2p1:LockId>
<d2p1:LockType>G2</d2p1:LockType>
<d2p1:MultiCode>String</d2p1:MultiCode>
<d2p1:OnetimeCode>String</d2p1:OnetimeCode>
<d2p1:SerialNumber>23-33-44-02846</d2p1:SerialNumber>
</Lock>
</SaveLockResponse>
Now i want this to be converted back to c# object, And i follow the below code,
public static T DeserializeFromXml<T>(string xml)
{
T result;
XmlSerializer ser = new XmlSerializer(typeof(T));
using (TextReader tr = new StringReader(xml))
{
result = (T)ser.Deserialize(tr);
}
return result;
}
When i call this method i will get error as below,
There is an error in XML document (1, 40).And inner exception as
{"http://www.easy2access.no/webservice/types'> was not expected."}
Any suggesions most welcome!.
Regards
Sangeetha
Related
I am creating a system that stores vehicle data. When I serialize the data using Xml serialization, I get the correct format as shown in the example below:
<?xml version="1.0"?>
<ArrayOfVehicle xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Vehicle>
<Registration>fake1</Registration>
<Model>123</Model>
<Make>test</Make>
<Year>1999</Year>
<Cost>100</Cost>
</Vehicle>
<Vehicle>
<Registration>fake2</Registration>
<Model>321</Model>
<Make>123</Make>
<Year>2000</Year>
<Cost>321</Cost>
</Vehicle>
</ArrayOfVehicle>
The serialization uses a list of vehicles that have the attributes seen in the Xml file. I am trying to figure out how I can delete a vehicle from the list and serialize it back to the Xml file without breaking the format shown above.
The method that I have tried to use to delete the records from the list and serialize and deserialize the data, but when I remove and item, it breaks the format. This is what the Xml file looks like when I remove an item from the list and serialize it:
fake1 123 test 1999 100
Here is my code for removing an item:
for (int i = Business.VehicleList.Count - 1; i >= 0; i--)
{ //Where Business.VehicleList is my list
if (Business.VehicleList[i].Registration == registration)
{
Business.VehicleList.RemoveAt(i);
Business.Save(); //Method for serialization
}
}
Here is the error it throws when I try to deserialize the data again:
System.InvalidOperationException: 'There is an error in XML document (10, 19). XmlException: There are multiple root elements. Line 10, position 19.'
These are my serialization and deserialization methods:
public static void Retrieve()
{
using (FileStream fileStream = new FileStream("C:\\temp\\data.xml", FileMode.OpenOrCreate))
{
using (var reader = new StreamReader(fileStream))
{
if (fileStream.Length <= 0)
{
return;
}
else
{
XmlSerializer deserializer = new XmlSerializer(typeof(List<Vehicle>),
new XmlRootAttribute("ArrayOfVehicle"));
_vehicleList = (List<Vehicle>)deserializer.Deserialize(reader); //This is where the error is thrown
}
}
}
}
public static void Save()
{
XmlSerializer serializer = new XmlSerializer(typeof(List<Vehicle>));
using (FileStream fileStream = new FileStream("C:\\temp\\data.xml", FileMode.Open))
{
serializer.Serialize(fileStream, VehicleList);
fileStream.Close();
}
}
Any suggestions on how to remove a vehicle from my list without it breaking the Xml file?
Here is the source after I tried deleting an item from the vehicle string
<?xml version="1.0"?>
<ArrayOfVehicle xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Vehicle>
<Registration>123</Registration>
<Model>123</Model>
<Make>23</Make>
<Year>2000</Year>
<Cost>123</Cost>
</Vehicle>
</ArrayOfVehicle><Registration>1321</Registration>
<Model>123123</Model>
<Make>312312</Make>
<Year>2000</Year>
<Cost>321</Cost>
</Vehicle>
</ArrayOfVehicle>
In the Save method, new FileStream("C:\\temp\\data.xml", FileMode.Open) will open the existing file without truncating it. So after you write the new XML data to the file, there will be remnants of the old content if the new content is shorter than the old one.
Changing this to new FileStream("C:\\temp\\data.xml", FileMode.Create) will fix the issue.
I think it's because you are trying to de-serialize a malformed xml. Please first, make sure that your serialization method produces correct xml. The reason may be because of closing the stream inside using statement. And also serializing the list before for-loop finishes.
Try removing fileStream.Close(); and also moving Business.Save(); to outside of for-loop.
Here, I made a fiddle with same conditions and it works.
Im trying to deserialize an array of objects from a XML Document.
The document built in the following structure:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<element>
.....
</element>
<element>
.....
</element>
</root>
But for some reason Im having lots of problems doing so.
This is my function which I call to deserialize it:
public static CardModel[] Load(string text)
{
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "root";
xRoot.IsNullable = true;
XmlSerializer serializer = new XmlSerializer(typeof(CardModel[]),xRoot);
StringReader reader = new StringReader(text);
CardModel[] o = serializer.Deserialize(reader) as CardModel[];
reader.Close();
return o;
}
And I am not sure if its done correctly or not. Because I know that in json you are unable to deserialize an array and you have to do some sort of "hack".
In the CardModel class (which is the element of the array) i use above the class the tag [XmlRoot("root")]. I have also tried to use [XmlRoot("element")] but still im getting stuck.
Afaik you can't directly deserialize into an array but would need a wrapper class like
[Serializable]
[XMLRoot("root")]
public class Root
{
// This does the magic of treating all "element" items nested under the root
// As part of this array
[XmlArray("element")]
public CardModel[] models;
}
And rather deserilialize into that like
public static CardModel[] Load(string text)
{
// I don't think that you need the attribute overwrite here
var serializer = new XmlSerializer(typeof(Root));
using(var reader = new StringReader(text))
{
var root = (Root) serializer.Deserialize(reader);
return root.models;
}
}
I have problem when I'm trying to deserialize an XML to object. My XML look like:
<?xml version="1.0" encoding="utf-16"?>
<Products
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<AllProducts>
<Product>
<ID>8</ID>
<GID>51280</GID>
<Kod>RNIKAKC1.6</Kod>
<Name>SB-800</Name>
<Ean>0018208048014</Ean>
<CommodityGroup>
<ID>86</ID>
<Name>AKCESORIA FOTO</Name>
<Path>
<Category>
<ID>60798</ID>
<Name>ARCHIWALNE</Name>
</Category>
</Path>
</CommodityGroup>
</Product>
....
Next products
...
My method code:
var MemoryStream = APIAccess.DownloadFileToStream("example.xml", "exampleContainer");
using (MemoryStream)
{
MemoryStream.Position = 0;
using (StreamReader StreamReader = new StreamReader(MemoryStream))
{
XmlSerializer serializer = new XmlSerializer(typeof(CommodityGroup));
var products = serializer.Deserialize(StreamReader);
}
}
Method DownloadFileToStream is working good, because it is useful in other classes.
I'm geting error:
InvalidOperationException: Products xmlns='' was not expected.
I want to create object of a Node CommodityGroup. I've created class selecting this node, coping it and pasting in the new class like Paste Special -> XML
Attributes of this class looks like:
[Serializable()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[XmlTypeAttribute(AnonymousType = true)]
[XmlRootAttribute(Namespace = "CommodityGroup", IsNullable = false)]
I don't know to fix it. When I'm adding into XML Serializer param new XmlRootAttribute("Products"), I'm getting "0" values.
Do you have any suggestions?
If you want to deserialize only part of an xml document, you should skip unnecessary nodes.
Do it using XmlReader.
using (StreamReader StreamReader = new StreamReader(MemoryStream))
using (var xmlReader = XmlReader.Create(StreamReader))
{
xmlReader.ReadToFollowing("CommodityGroup");
XmlSerializer serializer = new XmlSerializer(typeof(CommodityGroup));
var commodityGroup = (CommodityGroup)serializer.Deserialize(xmlReader);
}
I want to get an object from an xml file. In my example I am using iso 2002 pain.001.001.03
I have downloaded the schema from
pain.001.001.03.xsd
and the xml file from
pain.001.001.03.xml
I have validated my xml against the xsd using this tool
Validate XML
I have generated a class using xsd
and I am using the code below in order to deserialize
XmlSerializer ser = new XmlSerializer(typeof(CustomerCreditTransferInitiationV03), new XmlRootAttribute
{
ElementName = "Document",
Namespace = "urn:iso:std:iso:20022:tech:xsd:pain.001.001.03",
});
FileStream myFileStream = new FileStream("C:\\001.001.03\\pain.001.001.03.xml", FileMode.Open);
CustomerCreditTransferInitiationV03 myObject = (CustomerCreditTransferInitiationV03) ser.Deserialize(myFileStream);
The code return null values but my xml has values
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03">
<CstmrCdtTrfInitn>
The root element is an Document, and not a CstmrCdtTrfInitn :
var serializer = new XmlSerializer(typeof(Document));
using (var file = File.OpenRead(path))
{
var document = (Document)serializer.Deserialize(file);
var transfer = document.CstmrCdtTrfInitn;
}
I have been given an XML file and an XSD file. I am trying to validate the XML against the XSD and then, using Serialization, load the the XML into an object.
I have the validation working as expected but when I try to DeserializeDocToObj I get the following error.
There was an error deserializing the object of type
Aaa.Bbb.Common.DataTypes.SurveyGroup. Processing instructions
(other than the XML declaration) and DTDs are not supported.
Line 1, position 2.
I have no idea what this means and all I have read is not really helping.
The header in the XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.mydomain.co.uk/srm/mscc"
targetNamespace="http://www.mydomain.co.uk/srm/mscc"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="SurveyGroup">
The header in the XML
<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="mscc4_cctv.xsl"?>
<SurveyGroup xmlns="http://www.mydomain.co.uk/srm/mscc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.mydomain.co.uk/srm/mscc
http://www.mydomain.co.uk/srm/schemas/mscc4_cctv.xsd">
<Survey>
Deserialization Code:
public T DeserializeDocToObj(string fileLocation)
{
T returnObj;
using (FileStream reader = new FileStream(fileLocation, FileMode.Open, FileAccess.Read))
{
DataContractSerializer ser = new DataContractSerializer(typeof(T));
returnObj = (T)ser.ReadObject(reader);
}
return returnObj;
}
Any help greatly appreciated
Create an XmlReader with the correct XmlReaderSettings and call DataContractSerializer.ReadObject(XmlReader) instead of DataContractSerializer.ReadObject(Stream):
using (var reader = XmlReader.Create(fileName, new XmlReaderSettings { IgnoreProcessingInstructions = true }))
{
var serializer = new DataContractSerializer(typeof(T));
return (T)serializer.ReadObject(reader);
}
The XmlReader used by DataContractSerializer.Read(Stream) does not IgnoreProcessingInstructions. DataContractSerializer.Read(Stream) calls XmlDictionaryReader.CreateTextReader (see the source) which creates a XmlUTF8TextReader (see the source) which does not accept XmlReaderSettings.
Apparently the default behaviour is to crap on (unknown) processing instructions. And the string <?xml-stylesheet type="text/xsl" href="mscc4_cctv.xsl"?> is a processing instruction as C.M. Sperberg-McQueen states.
The string <?xml-stylesheet type="text/xsl" href="mscc4_cctv.xsl"?> is a processing instruction. Your software is telling you it cannot handle processing instructions in its input. This means that your software appears not to be an XML parser; you need either to restrict your input to the subset of XML it can handle, or get a real parser.