In my project i am accessing xml file data with linq, xml file containing images in binary format.
I want to read that xml file and assign that image in xml file to picturebox on my form.
However I am not able to do that: while i am applying queries on xml file it is not understanding datatype for any element...
What is the problem?
This is my sample xml file & code in c#::
/////////xml file agency.xml////////////
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="agency">
<xs:complexType>
<xs:sequence>
<xs:element name="no" type="xs:int" minOccurs="0" />
<xs:element name="Name" type="xs:string" minOccurs="0" />
<xs:element name="Slogan" type="xs:string" minOccurs="0" />
<xs:element name="Vatno." type="xs:int" minOccurs="0" />
<xs:element name="MainBranch" type="xs:string" minOccurs="0" />
<xs:element name="Disclaimer" type="xs:string" minOccurs="0" />
<xs:element name="Logo" type="xs:base64Binary" minOccurs="0" />
<xs:element name="street" type="xs:string" minOccurs="0" />
<xs:element name="town_x002F_city" type="xs:string" minOccurs="0" />
<xs:element name="State_x002F_Country" type="xs:string" minOccurs="0" />
<xs:element name="PostalCode" type="xs:int" minOccurs="0" />
<xs:element name="Phone1" type="xs:int" minOccurs="0" />
<xs:element name="Phone2" type="xs:int" minOccurs="0" />
<xs:element name="Fax" type="xs:int" minOccurs="0" />
<xs:element name="Emailid" type="xs:string" minOccurs="0" />
<xs:element name="Website" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<agency>
<no>1</no>
<Name>Good Deal Pvt</Name>
<Slogan>We Values of Your Money</Slogan>
<Vatno.>123</Vatno.>
<MainBranch>Your Branch One</MainBranch>
<Disclaimer>All the information is legal still the buyer should collect other details if needed. This intended to give information & not part of any agreement.</Disclaimer>
<Logo>here is actually that lengthy binary data for image, i have edit that </Logo>
<street>Link Raod, Near Satara Road,Pune</street>
<town_x002F_city>Pune</town_x002F_city>
<State_x002F_Country>Mahrastra</State_x002F_Country>
<PostalCode>231231</PostalCode>
<Phone1>1231313</Phone1>
<Phone2>12312323</Phone2>
<Fax>1231231</Fax>
<Emailid>Gooddeal#gmail.com</Emailid>
<Website>www.gooddeal.com</Website>
</agency>
</NewDataSet>
////////sample code c# code to access above xml file//////////
XDocument doc = XDocument.Load("c:\\xml1\\agency.xml");
var result = from agen in doc.Descendants("agency")
where (int)agen.Element("no") == 1
select// agen;
new
{
no = (string)agen.Element("no"),
Name =(string) agen.Element("Name"),
Slogan = (string)agen.Element("Slogan"),
logo = agen.Element("Logo")
};
foreach (var tuple in result)
{
textbox1.text=tuple.Name;
textbox2.text=tuple.Slogan;
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(tuple.logo.ToString()));
Bitmap bmap = new Bitmap(ms);
this.pictureBox1.Image = bmap;
}
When image data or byte array serializa into XML it is basically base64 encoded data.
You have to first convert base64 to byte array.
http://msdn.microsoft.com/en-us/library/system.convert.frombase64string.aspx
Then load that data into memory stream.
then ms.Location = 0 ( memory stream starting location)
Than use in bitmap .
Thanks.
Related
I have an XML file
perhaps i usually do more than 100 query every minute with C# and XMLDatareader, that's why i am thinking to add an Index on it, is it possible? or Indexes are allowed only on DB like sqlserver/mysql?
thanks
Here my XML file, with the first record:
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Traduzioni">
<xs:complexType>
<xs:sequence>
<xs:element name="Path" type="xs:string" />
<xs:element name="IT" type="xs:string" minOccurs="0" />
<xs:element name="EN" type="xs:string" minOccurs="0" />
<xs:element name="FR" type="xs:string" minOccurs="0" />
<xs:element name="PT" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="extension_ref">
<xs:complexType>
<xs:sequence>
<xs:element name="idKey" type="xs:string" minOccurs="0" />
<xs:element name="Reference" type="xs:string" minOccurs="0" />
<xs:element name="Ordine" type="xs:string" minOccurs="0" />
<xs:element name="Dizione_EN" type="xs:string" minOccurs="0" />
<xs:element name="Dizione_IT" type="xs:string" minOccurs="0" />
<xs:element name="Dizione_PT" type="xs:string" minOccurs="0" />
<xs:element name="Dizione_FR" type="xs:string" minOccurs="0" />
<xs:element name="Dizione_SP" type="xs:string" minOccurs="0" />
<xs:element name="idKey_old" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:unique name="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//Traduzioni" />
<xs:field xpath="Path" />
</xs:unique>
</xs:element>
</xs:schema>
<Traduzioni>
<Path>N.Ordine</Path>
<IT>N.Ordine</IT>
<EN>Order number</EN>
<FR>Numéro de commande</FR>
<PT>No de ordem:</PT>
</Traduzioni>
That looks like a translation file of some sort.
You'd be best off loading the XML into memory, e.g. a Dictionary<string, Dictionary<string, string>>, keyed by target language, then by original string. (This is rather trivial to do, so I won't post the code here.)
That way you can then access translations with
translations["EN"]["N.Ordine"]
I'm working on building an XML editor for a personal project. Using WinForms DataGridView control and DataSet, I was able to set up Read/Edit/Save with little issue, using a separate XML file for each type.
However, as I started to try adding more "advanced" controls, it became cumbersome to work with several different files - requiring if statements depending on which file I was working with. So, I tried combining these files into one larger file, as below:
<?xml version="1.0" encoding="utf-8" ?>
<Items>
<Armor>
<Item>
<Name>Test Armor</Name>
<Value>1234567</Value>
<Rarity>Common</Rarity>
<Slot>Chest</Slot>
<Damage>1234567</Damage>
<Defense>1234567</Defense>
<Health>1234567</Health>
<Mana>1234567</Mana>
<Strength>1234567</Strength>
<Dexterity>1234567</Dexterity>
<FlavorText>Something about stuff</FlavorText>
<ImageSource>C:\Items\img.gif</ImageSource>
</Item>
</Armor>
<Consumables>
<Item>
<Name>Test Potion</Name>
<Value>1234567</Value>
<Damage>1234567</Damage>
<Defense>1234567</Defense>
<Health>0.1234567</Health>
<Mana>0.1234567</Mana>
<Strength>1234567</Strength>
<Dexterity>1234567</Dexterity>
<FlavorText>Something about stuff</FlavorText>
<ImageSource>C:\Items\img.gif</ImageSource>
</Item>
</Consumables>
<Junk>
<Item>
<Name>Test Junk</Name>
<Value>1234567</Value>
<Stackable>Yes</Stackable>
<FlavorText>Something about stuff</FlavorText>
<ImageSource>C:\Items\img.gif</ImageSource>
</Item>
</Junk>
<QuestItems>
<Item>
<Name>Test Quest Item</Name>
<Stackable>Yes</Stackable>
<FlavorText>Something about stuff</FlavorText>
<ImageSource>C:\Items\img.gif</ImageSource>
</Item>
</QuestItems>
<Weapons>
<Item>
<Name>Test Weapon</Name>
<Value>1234567</Value>
<Rarity>Common</Rarity>
<Slot>Primary</Slot>
<Damage>1234567</Damage>
<Defense>1234567</Defense>
<Health>1234567</Health>
<Mana>1234567</Mana>
<Strength>1234567</Strength>
<Dexterity>1234567</Dexterity>
<FlavorText>Something about stuff</FlavorText>
<ImageSource>C:\Items\img.gif</ImageSource>
</Item>
</Weapons>
</Items>
And the schema, generated from Visual Studio's Create Schema menu, and minimally modified - such as changing unsignedInt to int:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Items">
<xs:complexType>
<xs:sequence>
<xs:element name="Armor">
<xs:complexType>
<xs:sequence>
<xs:element name="Item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Value" type="xs:int" />
<xs:element name="Rarity" type="xs:string" />
<xs:element name="Slot" type="xs:string" />
<xs:element name="Damage" type="xs:int" />
<xs:element name="Defense" type="xs:int" />
<xs:element name="Health" type="xs:int" />
<xs:element name="Mana" type="xs:int" />
<xs:element name="Strength" type="xs:int" />
<xs:element name="Dexterity" type="xs:int" />
<xs:element name="FlavorText" type="xs:string" />
<xs:element name="ImageSource" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Consumables">
<xs:complexType>
<xs:sequence>
<xs:element name="Item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Value" type="xs:int" />
<xs:element name="Damage" type="xs:int" />
<xs:element name="Defense" type="xs:int" />
<xs:element name="Health" type="xs:decimal" />
<xs:element name="Mana" type="xs:decimal" />
<xs:element name="Strength" type="xs:int" />
<xs:element name="Dexterity" type="xs:int" />
<xs:element name="FlavorText" type="xs:string" />
<xs:element name="ImageSource" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Junk">
<xs:complexType>
<xs:sequence>
<xs:element name="Item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Value" type="xs:int" />
<xs:element name="Stackable" type="xs:string" />
<xs:element name="FlavorText" type="xs:string" />
<xs:element name="ImageSource" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="QuestItems">
<xs:complexType>
<xs:sequence>
<xs:element name="Item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Stackable" type="xs:string" />
<xs:element name="FlavorText" type="xs:string" />
<xs:element name="ImageSource" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Weapons">
<xs:complexType>
<xs:sequence>
<xs:element name="Item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Value" type="xs:int" />
<xs:element name="Rarity" type="xs:string" />
<xs:element name="Slot" type="xs:string" />
<xs:element name="Damage" type="xs:int" />
<xs:element name="Defense" type="xs:int" />
<xs:element name="Health" type="xs:int" />
<xs:element name="Mana" type="xs:int" />
<xs:element name="Strength" type="xs:int" />
<xs:element name="Dexterity" type="xs:int" />
<xs:element name="FlavorText" type="xs:string" />
<xs:element name="ImageSource" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Both of these files are wholly representative of their counterparts - I had separate files for Armor, Consumables, etc.
The expected outcome was to have one file representing the previously separate files, such that:
Items is the root node.
Within Items are the parent nodes - Armor, Consumables, etc.
Within each parent node are the child nodes Item and their properties.
As far as I can tell, the XML structure and schema looks correct, but when I try to read this file into my program, I receive the error: System.FormatException - "Input string was not in a correct format.".
The stack trace shows that System.Number.StringToNumber is throwing this exception. I've dug through the file and the schema a few times and can't seem to find where this is occuring, and the exception detail doesn't provide much further detail.
In my code, I'm reading the data simply using
DataSet data = new DataSet();
data.ReadXmlSchema(itemSchema);
data.ReadXml(itemData);
This exact method worked without issue when the files/schema were separate, which further leads me to believe I've simply overlooked something in the XML/Schema.
At this point, I'm stuck and not sure what it could be. I would greatly appreciate if anyone can help me solve this issue.
The problem is that you repeat the element Item on each item type.
When your code reads the schema, it finds the first appearance of the Item element and tries to apply the same schema to every other appearance; so, when it reads the Test Potion it tries to read it as string, int, string, string, int, int, int, int, int, int, string, string and fails when it finds the 0.1234567 Health value.
My suggestion would be to change your schema it to something like this:
<?xml version="1.0" encoding="utf-8" ?>
<Items>
<Armor>
<ArmorItem>
...Item elements
</ArmorItem>
</Armor>
<Consumables>
<ConsumableItem>
...Item elements
</ConsumableItem>
</Consumables>
<Junk>
<JunkItem>
...Item elements
</JunkItem>
</Junk>
<QuestItems>
<QuestItem>
...Item elements
</QuestItem>
</QuestItems>
<Weapons>
<WeaponItem>
...Item elements
</WeaponItem>
</Weapons>
</Items>
I tried to generate xsd from 2 xml documents. In those 2 xml documents, there are some simple elements (<SubTotal> and <Tax>) and complex type element (<SubTotals>) are optional; that means they may be present or absent from XML documents. Below are 2 sample XML documents and 1 broken xsd document.
I generated xsd document, but it did not work well. By using generated xsd document, when I validated XML documents, the first XML document was valid but the second xml document was not. I want that the xsd should work well with both XML documents. The xml data in those 2 xml documents are valid.
In the first xml document, optional simple type <SubTotal> and <Tax> elements are present, but optional complex type <SubTotals> element is absent.
In the second xml document, optional complex type <SubTotals> element is present, but 2 optional simple type <SubTotal> and <Tax> elements are absent.
The following is the 1st xml document. Is was validated successfully.
<ReceiptMessage>
<DeviceId>AA-BB-CC-DD-EE-FF</DeviceId>
<From>temp#somewhere.com</From>
<To>abc#xyz.com</To>
<Subject>Your Receipt - Version 1</Subject>
<OptIn>255</OptIn>
<Receipt>
<CheckNo>13254</CheckNo>
<TableId>1</TableId>
<ReceiptDate>2015-09-23T11:20:00</ReceiptDate>
<Server>Joy Server</Server>
<CardNo>48757-Loyalty</CardNo>
<PaymentMode>Credit Card</PaymentMode>
<ReceiptHeader>
<string>Some Header 1</string>
<string>Some header 2</string>
</ReceiptHeader>
<SubTotal>35.00</SubTotal>
<Tax>1.00</Tax>
<Total>36.00</Total>
<Gratuity>2.00</Gratuity>
<SplitCheckTotal>38.00</SplitCheckTotal>
<Tip>1.50</Tip>
<AmountPaid>39.50</AmountPaid>
<ReceiptItems>
<ReceiptItem>
<ItemName>Pizza Hut ABC</ItemName>
<Qty>2</Qty>
<Price>4.00</Price>
</ReceiptItem>
<ReceiptItem>
<ItemName>Burito 289</ItemName>
<Qty>1</Qty>
<Price>8.35</Price>
</ReceiptItem>
</ReceiptItems>
<ReceiptFooter>
<string>Thank you for your shopping at our site</string>
<string>Please come back</string>
</ReceiptFooter>
<ReceiptSurvey>
<string>Survey 1 content</string>
<string>Survey - go to our site and register for sweeptakes</string>
</ReceiptSurvey>
</Receipt>
</ReceiptMessage>
The following is the 2nd xml document. Is was not valid.
<ReceiptMessage>
<DeviceId>AA-BB-CC-DD-EE-FF</DeviceId>
<From>temp#somedomain.com</From>
<To>abc#somedomain.com</To>
<Subject>Your Receipt from XYZ- Version 2</Subject>
<OptIn>255</OptIn>
<Receipt>
<CheckNo>17282</CheckNo>
<TableId>Table ABC</TableId>
<ReceiptDate>2015-09-23T16:32:59.4561339-05:00</ReceiptDate>
<Server>John Doe</Server>
<CardNo>2920202</CardNo>
<PaymentMode>Credit Card</PaymentMode>
<ReceiptHeader>
<string>Header 1</string>
<string>Header 2</string>
</ReceiptHeader>
<SubTotals>
<SubtotalItem Label="Subtotal">25.00</SubtotalItem>
<SubtotalItem Label="Sales Tax">3.00</SubtotalItem>
<SubtotalItem Label="City Tax">1.15</SubtotalItem>
<SubtotalItem Label="County Tax">2.25</SubtotalItem>
<SubtotalItem Label="State Tax">1.25</SubtotalItem>
</SubTotals>
<Total>32.65</Total>
<Gratuity>2.00</Gratuity>
<SplitCheckTotal>0.5</SplitCheckTotal>
<Tip>3.00</Tip>
<AmountPaid>38.15</AmountPaid>
<ReceiptItems>
<ReceiptItem>
<ItemName>Pizza</ItemName>
<Qty>1</Qty>
<Price>5.32</Price>
</ReceiptItem>
<ReceiptItem>
<ItemName>Burito</ItemName>
<Qty>2</Qty>
<Price>10.99</Price>
</ReceiptItem>
</ReceiptItems>
<ReceiptFooter>
<string>Footer 1</string>
<string>Footer 2</string>
</ReceiptFooter>
<ReceiptSurvey>
<string>Go to our site to register and win awards to</string>
</ReceiptSurvey>
</Receipt>
</ReceiptMessage>
I would like to have a correct version for the following generated xsd. It should work with those 2 XML documents.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="ReceiptMessage" nillable="true" type="ReceiptMessage" />
<xs:complexType name="ReceiptMessage">
<xs:complexContent mixed="false">
<xs:extension base="EmailParams">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="OptIn" type="xs:unsignedByte" />
<xs:element minOccurs="0" maxOccurs="1" name="Receipt" type="ReceiptData" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="EmailParams">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="DeviceId" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="From" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="To" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="Subject" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="ReceiptData">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="CheckNo" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="TableId" type="xs:string" />
<xs:element minOccurs="1" maxOccurs="1" name="ReceiptDate" type="xs:dateTime" />
<xs:element minOccurs="0" maxOccurs="1" name="Server" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="CardNo" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="PaymentMode" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="ReceiptHeader" type="ArrayOfString" />
<xs:element minOccurs="1" maxOccurs="1" name="SubTotal" nillable="true" type="xs:double" />
<xs:element minOccurs="1" maxOccurs="1" name="Tax" nillable="true" type="xs:double" />
<xs:element minOccurs="0" maxOccurs="1" name="SubTotals" type="ArrayOfSubtotalItem" />
<xs:element minOccurs="1" maxOccurs="1" name="Total" type="xs:double" />
<xs:element minOccurs="1" maxOccurs="1" name="Gratuity" type="xs:double" />
<xs:element minOccurs="1" maxOccurs="1" name="SplitCheckTotal" type="xs:double" />
<xs:element minOccurs="1" maxOccurs="1" name="Tip" type="xs:double" />
<xs:element minOccurs="1" maxOccurs="1" name="AmountPaid" type="xs:double" />
<xs:element minOccurs="0" maxOccurs="1" name="ReceiptItems" type="ArrayOfReceiptItem" />
<xs:element minOccurs="0" maxOccurs="1" name="ReceiptFooter" type="ArrayOfString" />
<xs:element minOccurs="0" maxOccurs="1" name="ReceiptSurvey" type="ArrayOfString" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArrayOfString">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArrayOfSubtotalItem">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="SubtotalItem" nillable="true" type="SubtotalItem" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="SubtotalItem">
<xs:simpleContent>
<xs:extension base="xs:double">
<xs:attribute name="Label" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="ArrayOfReceiptItem">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="ReceiptItem" nillable="true" type="ReceiptItem" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="ReceiptItem">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="ItemName" type="xs:string" />
<xs:element minOccurs="1" maxOccurs="1" name="Qty" type="xs:double" />
<xs:element minOccurs="1" maxOccurs="1" name="Price" type="xs:double" />
</xs:sequence>
</xs:complexType>
</xs:schema>
I use the following free online tool to validate my XML documents based on generated XSD:
http://www.freeformatter.com/xml-validator-xsd.html
Your code has:
<xs:element minOccurs="1" maxOccurs="1" name="SubTotal" nillable="true" type="xs:double" />
<xs:element minOccurs="1" maxOccurs="1" name="Tax" nillable="true" type="xs:double" />
And you wrote that sometimes Tax or SubTotal can be absent. In other words, the minOccurs should be set to 0.
Typically, when you auto-generate an XSD from an instance XML document, there will be gaps that the XSD generator will not be able to assess, simply because information in an instance XML document will never be complete.
At best, such auto-generation gets you going, but you'll always have to do some tweaks afterwards. Use a good (graphical) XSD designer (oXygen, Visual Studio, Eclipse, LiquidXML etc) which lets you drag/drop and set properties through a convenient interface.
I am using C# 4.5/Visual Studio 2012 to try to load an XML file to a DataSet. I read the instructions here:
http://msdn.microsoft.com/en-us/library/fx29c3yd.aspx
I am loading an XML file that looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<UnitTestDataSet xmlns="https://rebuildinghomes.codeplex.com/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://rebuildinghomes.codeplex.com/ UnitTestLoadData.xsd">
<Person>
<PersonId>1111</PersonId>
<FirstName>Unit</FirstName>
<LastName>Tester</LastName>
</Person>
</UnitTestDataSet>
With a schema like this:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="RebuildingUnitTestData"
targetNamespace="https://rebuildinghomes.codeplex.com/"
xmlns:u="https://rebuildinghomes.codeplex.com/"
elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:complexType name="PersonType">
<xs:sequence>
<xs:element name="PersonId" type="xs:int"
minOccurs="1" maxOccurs="1" />
<xs:element name="FirstName" type="xs:string"
minOccurs="1" maxOccurs="1" />
<xs:element name="LastName" type="xs:string"
minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:schema>
Using the following C# code:
//Load init/expected
DataSet init = new DataSet();
init.ReadXmlSchema("RebuildingModel/Data/UnitTestLoadData.xsd");
init.ReadXml("RebuildingModel/Data/PersonUnitTest.xml", XmlReadMode.ReadSchema);
However, when I look at "init" in the debugger, the DataSet is empty. What am I doing wrong?
Sadly, your snippet of code seem to work on my machine. Are you sure you're checking init AFTER the init.ReadXml() statement executes?
See my output from my Visual Studio immediate window below:
ds.Tables[0]
{Person}
base {System.ComponentModel.MarshalByValueComponent}: {Person}
CaseSensitive: false
ChildRelations: {System.Data.DataRelationCollection.DataTableRelationCollection}
Columns: {System.Data.DataColumnCollection}
Constraints: {System.Data.ConstraintCollection}
DataSet: {System.Data.DataSet}
DefaultView: {System.Data.DataView}
DisplayExpression: ""
ExtendedProperties: Count = 0
HasErrors: false
IsInitialized: true
Locale: {en-US}
MinimumCapacity: 50
Namespace: "https://rebuildinghomes.codeplex.com/"
ParentRelations: {System.Data.DataRelationCollection.DataTableRelationCollection}
Prefix: ""
PrimaryKey: {System.Data.DataColumn[0]}
RemotingFormat: Xml
Rows: {System.Data.DataRowCollection}
Site: null
TableName: "Person"
ds.Tables[0].Rows
{System.Data.DataRowCollection}
base {System.Data.InternalDataCollectionBase}: {System.Data.DataRowCollection}
Count: 1
My DataSet is populated with a single table containing a single row as per your XML.
I finally figured this out.
The schema now looks like this:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="UnitTestDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop">
<xs:annotation>
<xs:appinfo source="urn:schemas-microsoft-com:xml-msdatasource">
<DataSource DefaultConnectionIndex="0" FunctionsComponentName="QueriesTableAdapter" Modifier="AutoLayout, AnsiClass, Class, Public" SchemaSerializationMode="IncludeSchema" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<Connections />
<Tables />
<Sources />
</DataSource>
</xs:appinfo>
</xs:annotation>
<xs:element name="UnitTestDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true" msprop:Generator_DataSetName="UnitTestDataSet" msprop:Generator_UserDSName="UnitTestDataSet">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Person" msprop:Generator_TableClassName="PersonDataTable" msprop:Generator_TableVarName="tablePerson" msprop:Generator_TablePropName="Person" msprop:Generator_RowDeletingName="PersonRowDeleting" msprop:Generator_RowChangingName="PersonRowChanging" msprop:Generator_RowEvHandlerName="PersonRowChangeEventHandler" msprop:Generator_RowDeletedName="PersonRowDeleted" msprop:Generator_UserTableName="Person" msprop:Generator_RowChangedName="PersonRowChanged" msprop:Generator_RowEvArgName="PersonRowChangeEvent" msprop:Generator_RowClassName="PersonRow">
<xs:complexType>
<xs:sequence>
<xs:element name="PersonId" msprop:Generator_ColumnVarNameInTable="columnPersonId" msprop:Generator_ColumnPropNameInRow="PersonId" msprop:Generator_ColumnPropNameInTable="PersonIdColumn" msprop:Generator_UserColumnName="PersonId" type="xs:int" />
<xs:element name="FirstName" msprop:Generator_ColumnVarNameInTable="columnFirstName" msprop:Generator_ColumnPropNameInRow="FirstName" msprop:Generator_ColumnPropNameInTable="FirstNameColumn" msprop:Generator_UserColumnName="FirstName" type="xs:string" />
<xs:element name="LastName" msprop:Generator_ColumnVarNameInTable="columnLastName" msprop:Generator_ColumnPropNameInRow="LastName" msprop:Generator_ColumnPropNameInTable="LastNameColumn" msprop:Generator_UserColumnName="LastName" type="xs:string" />
<xs:element name="HomePhoneNbr" msprop:Generator_ColumnVarNameInTable="columnHomePhoneNbr" msprop:Generator_ColumnPropNameInRow="HomePhoneNbr" msprop:Generator_ColumnPropNameInTable="HomePhoneNbrColumn" msprop:Generator_UserColumnName="HomePhoneNbr" type="xs:string" minOccurs="0" />
<xs:element name="CellPhoneNbr" msprop:Generator_ColumnVarNameInTable="columnCellPhoneNbr" msprop:Generator_ColumnPropNameInRow="CellPhoneNbr" msprop:Generator_ColumnPropNameInTable="CellPhoneNbrColumn" msprop:Generator_UserColumnName="CellPhoneNbr" type="xs:string" minOccurs="0" />
<xs:element name="StreetAddress" msprop:Generator_ColumnVarNameInTable="columnStreetAddress" msprop:Generator_ColumnPropNameInRow="StreetAddress" msprop:Generator_ColumnPropNameInTable="StreetAddressColumn" msprop:Generator_UserColumnName="StreetAddress" type="xs:string" minOccurs="0" />
<xs:element name="AptNbr" msprop:Generator_ColumnVarNameInTable="columnAptNbr" msprop:Generator_ColumnPropNameInRow="AptNbr" msprop:Generator_ColumnPropNameInTable="AptNbrColumn" msprop:Generator_UserColumnName="AptNbr" type="xs:string" minOccurs="0" />
<xs:element name="City" msprop:Generator_ColumnVarNameInTable="columnCity" msprop:Generator_ColumnPropNameInRow="City" msprop:Generator_ColumnPropNameInTable="CityColumn" msprop:Generator_UserColumnName="City" type="xs:string" minOccurs="0" />
<xs:element name="County" msprop:Generator_ColumnVarNameInTable="columnCounty" msprop:Generator_ColumnPropNameInRow="County" msprop:Generator_ColumnPropNameInTable="CountyColumn" msprop:Generator_UserColumnName="County" type="xs:string" minOccurs="0" />
<xs:element name="StateProvCd" msprop:Generator_ColumnVarNameInTable="columnStateProvCd" msprop:Generator_ColumnPropNameInRow="StateProvCd" msprop:Generator_ColumnPropNameInTable="StateProvCdColumn" msprop:Generator_UserColumnName="StateProvCd" type="xs:string" minOccurs="0" />
<xs:element name="PostalCode" msprop:Generator_ColumnVarNameInTable="columnPostalCode" msprop:Generator_ColumnPropNameInRow="PostalCode" msprop:Generator_ColumnPropNameInTable="PostalCodeColumn" msprop:Generator_UserColumnName="PostalCode" type="xs:string" minOccurs="0" />
<xs:element name="CountryCode" msprop:Generator_ColumnVarNameInTable="columnCountryCode" msprop:Generator_ColumnPropNameInRow="CountryCode" msprop:Generator_ColumnPropNameInTable="CountryCodeColumn" msprop:Generator_UserColumnName="CountryCode" type="xs:string" minOccurs="0" />
<xs:element name="NumberOfYearsAtAddr" msprop:Generator_ColumnVarNameInTable="columnNumberOfYearsAtAddr" msprop:Generator_ColumnPropNameInRow="NumberOfYearsAtAddr" msprop:Generator_ColumnPropNameInTable="NumberOfYearsAtAddrColumn" msprop:Generator_UserColumnName="NumberOfYearsAtAddr" type="xs:int" minOccurs="0" />
<xs:element name="EmailAddress" msprop:Generator_ColumnVarNameInTable="columnEmailAddress" msprop:Generator_ColumnPropNameInRow="EmailAddress" msprop:Generator_ColumnPropNameInTable="EmailAddressColumn" msprop:Generator_UserColumnName="EmailAddress" type="xs:string" minOccurs="0" />
<xs:element name="GenderCode" msprop:Generator_ColumnVarNameInTable="columnGenderCode" msprop:Generator_ColumnPropNameInRow="GenderCode" msprop:Generator_ColumnPropNameInTable="GenderCodeColumn" msprop:Generator_UserColumnName="GenderCode" type="xs:string" minOccurs="0" />
<xs:element name="EthnicityCode" msprop:Generator_ColumnVarNameInTable="columnEthnicityCode" msprop:Generator_ColumnPropNameInRow="EthnicityCode" msprop:Generator_ColumnPropNameInTable="EthnicityCodeColumn" msprop:Generator_UserColumnName="EthnicityCode" type="xs:int" minOccurs="0" />
<xs:element name="BirthDate" msprop:Generator_ColumnVarNameInTable="columnBirthDate" msprop:Generator_ColumnPropNameInRow="BirthDate" msprop:Generator_ColumnPropNameInTable="BirthDateColumn" msprop:Generator_UserColumnName="BirthDate" type="xs:date" minOccurs="0" />
<xs:element name="ResidentStatus" msprop:Generator_ColumnVarNameInTable="columnResidentStatus" msprop:Generator_ColumnPropNameInRow="ResidentStatus" msprop:Generator_ColumnPropNameInTable="ResidentStatusColumn" msprop:Generator_UserColumnName="ResidentStatus" type="xs:int" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:unique name="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//Person" />
<xs:field xpath="PersonId" />
</xs:unique>
</xs:element>
</xs:schema>
The big thing that changed, as you'll notice, is all of the extraneous junk that Visual Studio adds in. Apparently, .NET needs some of this to load the data properly, most notably the primary key annotation. So the moral of the story: if you're going to load a DataSet from XML, create a schema through Visual Studio or be prepared to run it through XSLT to add all this stuff, or the results will be unpredictable, at best.
Could it be the space in the following:
xsi:schemaLocation="https://rebuildinghomes.codeplex.com/ UnitTestLoadData.xsd">
from your xml file?
I auto generated an xsd file from the below xml and used xsd2code to get a c# class. The problem is the entire xml doesn't deserialize.
Here is how I'm attempting to deserialize:
static void Main(string[] args)
{
using (TextReader textReader = new StreamReader("config.xml"))
{
// string temp = textReader.ReadToEnd();
XmlSerializer deserializer = new XmlSerializer(typeof(project));
project p = (project)deserializer.Deserialize(textReader);
}
}
here is the actual XML:
<?xml version='1.0' encoding='UTF-8'?>
<project>
<scm class="hudson.scm.SubversionSCM">
<locations>
<hudson.scm.SubversionSCM_-ModuleLocation>
<remote>https://svn.xxx.com/test/Validation/CPS DRTest DLL/trunk</remote>
</hudson.scm.SubversionSCM_-ModuleLocation>
</locations>
<useUpdate>false</useUpdate>
<browser class="hudson.scm.browsers.FishEyeSVN">
<url>http://fisheye.xxxx.net/browse/Test/</url>
<rootModule>Test</rootModule>
</browser>
<excludedCommitMessages></excludedCommitMessages>
</scm>
<openf>Hello there</openf>
<buildWrappers/>
</project>
When I run the above, the locations node remains null.
Here is the xsd that I'm using:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="project">
<xs:complexType>
<xs:all>
<xs:element name="openf" type="xs:string" minOccurs="0" />
<xs:element name="buildWrappers" type="xs:string" minOccurs="0" />
<xs:element name="scm" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="useUpdate" type="xs:string" minOccurs="0" msdata:Ordinal="1" />
<xs:element name="excludedCommitMessages" type="xs:string" minOccurs="0" msdata:Ordinal="2" />
<xs:element name="locations" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="hudson.scm.SubversionSCM_-ModuleLocation" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="remote" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="browser" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="url" type="xs:string" minOccurs="0" msdata:Ordinal="0" />
<xs:element name="rootModule" type="xs:string" minOccurs="0" msdata:Ordinal="1" />
</xs:sequence>
<xs:attribute name="class" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="class" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="project" />
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
Figured it out. When using xsd2code I had select options to target the 3.5 framework and include the xml attributes. It now deserializes as expected. Not sure which one did it, but works now.
According to this page '.' is not a valid XML tag name character, so you need to rename <hudson.scm.SubversionSCM_-ModuleLocation> to something without the dots.