I need help deserializing a XML file that i got on my machine. i have tried somthing like this.
private void button1_Click(object sender, EventArgs e)
{
DataSet ds = new DataSet();
XmlSerializer xmlSerializer = new XmlSerializer(typeof(DataSet));
FileStream readStream = new FileStream("D:\\Europoultry\\Connection Hjælp\\CIN_Example_2.xml", FileMode.Open);
ds = (DataSet)xmlSerializer.Deserialize(readStream);
readStream.Close();
dataGridView1.DataSource = ds.Tables[0];
}
but it says there is an error.
There is an error in XML-document (2, 2) System.InvalidOperationException: der is an error in XML-document(2,2): http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader'> was not expected.
I can post the XML document if it is needed but it is a long document. Hope some of you can help.
Here is a part of the XML document
<?xml version="1.0" encoding="utf-8"?>
<sh:StandardBusinessDocument xmlns:sh="http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader" xmlns:eanucc="urn:ean.ucc:2" xmlns:gdsn="urn:ean.ucc:gdsn:2" xmlns:align="urn:ean.ucc:align:2" xmlns:chemical_ingredient="urn:ean.ucc:align:chemical_ingredient:2" xmlns:food_beverage_tobacco="urn:ean.ucc:align:food_beverage_tobacco:2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader http://www.gdsregistry.org/2.8/schemas/sbdh/StandardBusinessDocumentHeader.xsd urn:ean.ucc:2 http://www.gdsregistry.org/2.8/schemas/CatalogueItemNotificationProxy.xsd urn:ean.ucc:2 http://www.gdsregistry.org/2.8/schemas/AttributeValuePairExtensionProxy.xsd urn:ean.ucc:2 http://www.gdsregistry.org/2.8/schemas/CaseLevelNonGTINLogisticsUnitExtensionProxy.xsd urn:ean.ucc:2 http://www.gdsregistry.org/2.8/schemas/TradeItemExtensionSpecificsProxy.xsd urn:ean.ucc:2 http://www.gdsregistry.org/2.8/schemas/ChemicalIngredientExtensionProxy.xsd urn:ean.ucc:2 http://www.gdsregistry.org/2.8/schemas/FoodAndBeverageTradeItemExtensionProxy.xsd">
<sh:StandardBusinessDocumentHeader>
<sh:HeaderVersion>1.0</sh:HeaderVersion>
<sh:Sender>
<sh:Identifier Authority="EAN.UCC">5790000011032</sh:Identifier>
</sh:Sender>
<sh:Receiver>
<sh:Identifier Authority="EAN.UCC">5790000500000</sh:Identifier>
</sh:Receiver>
<sh:DocumentIdentification>
<sh:Standard>EAN.UCC</sh:Standard>
<sh:TypeVersion>2.8</sh:TypeVersion>
<sh:InstanceIdentifier>DI-35346-34535-xt435345</sh:InstanceIdentifier>
<sh:Type>catalogueItemNotification</sh:Type>
<sh:CreationDateAndTime>2013-12-20T10:46:26+00:00</sh:CreationDateAndTime>
</sh:DocumentIdentification>
</sh:StandardBusinessDocumentHeader>
<eanucc:message>
<entityIdentification>
<uniqueCreatorIdentification>MSG-35346-34535-xt435345</uniqueCreatorIdentification>
<contentOwner>
<gln>5790000011032</gln>
</contentOwner>
</entityIdentification>
<eanucc:transaction>
<entityIdentification>
<uniqueCreatorIdentification>TRN-35346-34535-xt435345</uniqueCreatorIdentification>
<contentOwner>
<gln>5790000011032</gln>
</contentOwner>
</entityIdentification>
<command>
<eanucc:documentCommand>
<documentCommandHeader type="ADD">
<!--D8164-->
<entityIdentification>
<uniqueCreatorIdentification>CMD-35346-34535-xt435345</uniqueCreatorIdentification>
<contentOwner>
<gln>5790000011032</gln>
</contentOwner>
</entityIdentification>
</documentCommandHeader>
<documentCommandOperand>
<gdsn:catalogueItemNotification creationDateTime="2013-12-20T10:46:26+00:00" documentStatus="ORIGINAL" isReload="false">
<catalogueItem>
<catalogueItemState state="IN_PROGRESS"/>
<tradeItem>
<tradeItemUnitDescriptor>CASE</tradeItemUnitDescriptor>
<!--D8276-->
<tradeItemIdentification>
Try using xsd.exe for generating a c# class from this xml document.
There is an answer here: Generate C# class from XML
Then you can deserialize the xml document to the newly generated c# class
There are a few issues here that I can see. First, the XML you're trying to deserialize to a DataSet isn't a DataSet, so the deserialization would fail. Easiest way to do what you're trying to do is to make a set of POCOs that do represent your data, annotate them appropriately, and deserialize to those, and you can then use them as you would any other object. The exception you're getting, I believe is just that the XmlSerializer doesn't recognise your root element as being the one expected by the DataSet, or simply that it cannot correctly match the namespace. You can see more details about this here (https://msdn.microsoft.com/en-us/library/aa302290.aspx#trblshtxsd_topic5). Details of controlling XML Serialization/Deserialization via annotated POCOs can be found here (https://msdn.microsoft.com/en-us/library/2baksw0z(v=vs.110).aspx).
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.
I could use some help in reading this xml as an object in C#, the problem I have is with "ExtensionData" element, I can read everything in this xml except what's inside that element and I can't understand why, also I am receiving this xml the way it is, I can't alter it in any ways. I've tried pasting it as classes in visual studio, aswell as converting it using various websites but none of them were able to convert that node in an object.
<BufferEntitiesContainer>
<HeaderComandaBufferEntities>
<HeaderComandaBufferEntity>
<ProfilImportId>25</ProfilImportId>
<OrderNumber>999872748</OrderNumber>
<OrderDate>2021-03-12</OrderDate>
<BuyerILN>12345600</BuyerILN>
<BuyerName>CLIENT B2C</BuyerName>
<SalesDepartment>Vanzare WEB</SalesDepartment>
<Warehouse>A01</Warehouse>
<OrderCurrency>RON</OrderCurrency>
<DocumentFunctionCode>WB2C</DocumentFunctionCode>
<Remarks></Remarks>
<PaymentType></PaymentType>
<DeliveryPointILN>CIP-NX</DeliveryPointILN>
<OrderSerial>WB2C</OrderSerial>
<PaymentTerm></PaymentTerm>
<ExpectedDeliveryDate>2021-03-12</ExpectedDeliveryDate>
<ExtensionData><![CDATA[<ExtensionData>
<ExtensionFields>
<ExtensionTemplateID>3</ExtensionTemplateID>
<Fields>
<Root>
<Avans>0</Avans>
<PerioadaValabilitate dataInceput="1900-01-02" dataFinala="2078-12-31" />
<DS_CLIENT_ID>--</DS_CLIENT_ID>
<Nume_client>DAN NEDELCU</Nume_client>
<Adr_cod_post>011618</Adr_cod_post>
<Adr_judet>BUCURESTI</Adr_judet>
<Adr_loc>SECTOR 1</Adr_loc>
<Adr_str>NAUM</Adr_str>
<Adr_nr>1</Adr_nr>
<Adr_bl>1</Adr_bl>
<Adr_et>1</Adr_et>
<Adr_ap>1</Adr_ap>
<Adr_sect></Adr_sect>
<Nr_tel>0744835647</Nr_tel>
<Inf_gen>--</Inf_gen>
<Tip_pl>false</Tip_pl>
<Link_fact>--</Link_fact>
<Taxa_tr>0</Taxa_tr>
<Cupon_reducere>0</Cupon_reducere>
<CNP></CNP>
</Root>
</Fields>
</ExtensionFields>
</ExtensionData>]]></ExtensionData>
<OrderLines>
<DetaliuComanda>
<BuyerItemCode></BuyerItemCode>
<EAN>LEDLC-A6010E27/BC-WL</EAN>
<Remarks>Bec cu led A60 E27 10W 230V lumina rece Basic Well</Remarks>
<OrderedQuantity>1</OrderedQuantity>
<OrderedUnitNetPrice>8.8353</OrderedUnitNetPrice>
<UnitOfMeasure></UnitOfMeasure>
<Warehouse>A01</Warehouse>
</DetaliuComanda>
</OrderLines>
</HeaderComandaBufferEntity>
</HeaderComandaBufferEntities>
</BufferEntitiesContainer>
I managed to parse the string to an object this way:
XmlSerializer xmlSerializer = new XmlSerializer(typeof(BufferEntitiesContainer));
StreamReader streamReader = new StreamReader($#"{salesOrdersPath}{file}");
BufferEntitiesContainer so = (BufferEntitiesContainer)xmlSerializer.Deserialize(streamReader);
Console.WriteLine(so.HeaderComandaBufferEntities.HeaderComandaBufferEntity.ExtensionData);
XmlSerializer xmlInnerSerializer = new XmlSerializer(typeof(ExtensionData));
StringReader reader = new StringReader(so.HeaderComandaBufferEntities.HeaderComandaBufferEntity.ExtensionData);
ExtensionData soInner = (ExtensionData)xmlInnerSerializer.Deserialize(reader);
Console.WriteLine(soInner.ExtensionFields.Fields.Root.Nume_client);
So if anyone has this problem again, the solution was I made an object of type ExtensionData then I deserialized the inner xml string using StringReader to that object.
Thanks to all the people who gave me advices.
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.
I am using the follwing syntax to add data to already existing xml file in the following way:
XmlTextReader Reader = new XmlTextReader("ServerPaths.xml");
DataSet dsNewList = new DataSet();
dsNewList.ReadXml(Reader);
Reader.Close();
DataTable dt = dsNewList.Tables[0];
dt.Rows.Add(txtNewServerPath.Text);
dt.WriteXml("ServerPaths.xml",false);
But, i was getting error at last line as:
System.IO.IOException was unhandled
Message=The process cannot access the file 'C:\Documents and Settings\590000\my documents\visual studio 2010\Projects\EasyDeployer\EasyDeployer\bin\Debug\ServerPaths.xml' because it is being used by another process
Please help in solving this error. or is there any other way to do this?
My xml file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<ServerList>
<ServerPath>C:\\Avinash\\Dev1</ServerPath>
<ServerPath>C:\\Avinash\\Dev1</ServerPath>
</ServerList>
I just wanted to add new serverpath..
You could also try adding XmlNode's to the xml document like this:
XmlDocument xd = new XmlDocument();
xd.Load("ServerPaths.xml");
XmlNode rootNode = xd.DocumentElement;
XmlNode serverPathNode = xd.CreateElement("ServerPath");
serverPathNode.InnerText = txtNewServerPath.Text; // Your value
rootNode.AppendChild(serverPathNode);
xd.Save("ServerPaths.xml");
I am having trouble validating serialized data.
Ok, so I started with an XSD file which I got from some third party. Generated C# classes using xsd tool. Then I added
[XmlAttribute("noNamespaceSchemaLocation", Namespace = System.Xml.Schema.XmlSchema.InstanceNamespace)]
public string SchemaLocation = "http://localhost/schemas/AP_Transactions_10052011.xsd";
to the top level object. The URL in question is obviously accessible from my machine where I am running the code. Then I am serializing it using XmlSerializer, which correctly produces
<?xml version="1.0" encoding="utf-8"?>
<BU_AP_Vendor_Invoices xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="http://local.com/schemas/AP_Transactions_10052011.xsd">
...
</BU_AP_Vendor_Invoices>
So far so good.
Now I am trying to validate the file like so:
public static void Validate(TextReader xmlData)
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.ValidationFlags = XmlSchemaValidationFlags.ProcessIdentityConstraints | XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler += delegate(object sender, ValidationEventArgs args)
{
Console.WriteLine(args.Message);
};
using (XmlReader xmlReader = XmlReader.Create(xmlData, settings))
while (xmlReader.Read()) ;
}
Which results Could not find schema information for the element 'element name' warnings for every element in the XML file. I assume that means the XSD is simply not being loaded.
I was looking at the XmlReaderSettings.Schemas, but how would the reader know what to add there? I assumed that if I don't add schemas explicitly then magic will simply happen, but that doesn't seem to work.
Question is how to do this properly?
Please take a look at this post; the gist is to use XmlSchemaValidationFlags.ProcessSchemaLocation.