I have a design related question. So please guide me on how to do this?
Right now, I have a xml structure which will be in this format.
<Sheet id="abc"/>
<Elements>
<Element id="xyz">
<value>23</value>
</Element>
<Element id="sdz">
<value>46</value>
</Element>
...
</Elements>
</Sheet>
So, we have a class like this to store each & every element of the sheet.
Sheet
{
Public string SheetId
{
get; set;
}
//all Elements will be stored in the below collection
Public IList<IDictionary<string, string>> Elements
{
get; set;
}
}
But now for few sheets the format has been changed to the below structure.
<abc> //SheetId
<Elements>
<Record>
<Element1/>
<Element2/>
<Element3/>
<Element4/>
</Record>
<Record>
<Element1/>
<Element2/>
<Element3/>
<Element4/>
</Record>
...
</abc>
So, we need to create a Generic class to hold the above xml formats and we don't want to have different object to store these.
I mean in future if we have some other xml format also we need to accommodate the same without any change in the Sheet class.
So, can you please advise me on how to design the Sheet Class.?
Ok. let me explain how my app works.
Actually we have around 200 sheets(in other words measures).
1) User will upload the sheet data in xml format (all sheets in xml file) & edit the same if they want Or Enter the data in the screen (dynamic screen generated using the xml template) if they dont want to upload.
2) Then the data will be stored in the Sheet object and it will go through lot of Validation process and finally the data will be converted to xml again and stored in the db.
You can ask why you want to store this as XML? The reason is we dont want to create 200 aspx pages for this same kind of data and thats why we are generating the sheet pages dynamically using the xml templates. Also, we will be adding, updating or deleting sheets frequently.
Ok. I think now you will have some idea about this issue.
To be more clear, all the elements in my XML file will be displayed as a field in the aspx page. It maybe a Textbox, dropdown & etc....
I would recommend designing your class based on what the information actually represents and how your software plans to utilize the data, not the XML format being used.
You should always be able to do the transposition from the data format into the structure which best represents how your program will use this data.
Related
So I am developing an application that I want to be able to dynamically parse an xml file, grab attributes and populate a form that is created based on what elements are present in the xml file. Then the values can be edited, and written back to the xml file that was originally opened.
I've been able to parse, save values to a database , populate forms, and write back to the original xml file via hard coding, and I think I have an idea for the dynamic "database" structure (a dictionary where the key is a node's name, and the value is a dictionary if I wanna store a node's child node information, or a string if I'm in the furthest nested child node of an element).
I'm stuck on how to grab the information I need and how to store it in the "database" structure I've come up with. I've done research and have seen people use the "dynamic" object and linq. But everything I've seen seems to involve knowing the path names they've needed before run time. Any ideas on how I should be going about actually parsing the file and grabbing data, first off? I think if I can get that figured out, the rest should kind of fall into place.
Say I have this xml
<users>
<user1 age="43">John Doe</user1>
<user2 age="40">Jane Doe</user2>
</users>
An example database setup would look like Dictionary<users, Dictionary<user1, Dictionary<name,John Doe>
Where you could go Key("users").Key("user1").Key("name").Value to get John Doe or something like that.
Any other suggestions for my database setup would also be appreciated
It sounds like what you are looking for is XML serialization. Before you can do that though, you need to simplify your xml. Instead of numbering the <user> elements, you will want to use an attribute that has the value for the user id. For example you can use an id attribute.
<users>
<user id="1" age="43">John Doe</user>
<user id="2" age="40">Jane Doe</user>
</users>
Once you have done this, create a class that you can serialize to this xml.
using System.Xml.Serialization;
[XmlRoot(ElementName = "users")]
public class Users : List<User>
{
}
[XmlType(TypeName = "user")]
public class User
{
[XmlAttribute(AttributeName = "id")]
public int Id { get; set; }
[XmlAttribute(AttributeName = "age")]
public int Age { get; set; }
[XmlText]
public string Name { get; set; }
}
Then all you have to do to load from the file is deserialize.
XmlSerializer serializer = new XmlSerializer(typeof(Users));
Users users = (Users)serializer.Deserialize(File.OpenRead("XMLFile1.xml"));
You can use LINQ to query the Users collection for specific users.
var user1 = users.Where(u => u.Id == 1)
Modify the User objects or add more to the Users collection, then serialize to save changes back to the file.
XmlSerializer serializer = new XmlSerializer(typeof(Users));
serializer.Serialize(File.OpenWrite("XMLFile1.xml"), users);
You could parse xml using XmlDocument class. After parsing you have tree of nodes which you can traverse and show in UI. I don't understand why you want to save xml as distinct records of values in database, just save it as text. Anyway for saving xml you should translate its records back to xml.
I have an XML file in which I store data about a list of persons and another one in which I store a list of objects like this.
people.xml
<People>
<Person>
<Name>itsName</Name>
<Age> itsAge </Age>
<RecentAcquisitions>
<Acquisition>
<name>Apple</name>
<quantity>5</quantity>
</Acquisition>
</RecentAcquisitions>
</Person>
</People>
objects.xml
<Objects>
<Object>
<Name>Apple</Name>
<Description>Fresh Apple</Description>
<Price>10</Price>
<etc>..lots of attributes..</etc>
</Object>
</Objects>
What is the most efficient way of extracting information from objects.xml based on the person Acquisition List at the runtime? (in example the person should have 5 objects of type "Apple").
Momentarily I use a solution which consists of storing each object from objects.xml in a list and when I'm loading a person I search for the respective object based on Acquisition->Name and add it in the person.AquisitionList;
Is there another way of doing this?
Maybe I misunderstood the XML role but it feels wrong to store the information from an XML file in a list or array at runtime.
to my knowledge, using the runtime memory instead of constant read-write operations is the best way to do it / what you're doing is the right way.
XML can be seen as 2 things:
1 - A way to store information, much like a database, until it needs to be retrieved for processing at runtime
this is what you are doing now... you store the objects list on disk using XML, and then you retrieve it for processing/load it into memory at runtime.
2 - A standardized way of passing information around, regardless of technology.
XML can be read in a multitude of languages and any language that can read a string can technically read and extract the data from an XML document.
I need to generate a report in csv format. Data is retrieved as List<T> and only certain columns needs to be displayed in the report. I am thinking of doing it by storing its schema in an XML document under App_Data folder and use LINQ to XML to retrieve the field names and create the report.
Sample XML:
<report>
<fields>
<field headercaption='Customer Name'>CName</field>
<field headercaption='Address'>CAddress</field>
...
</fields>
</report>
Is it advisable to completely depend on XML file this way or do I need to do it through coding.
Edit
Fields are properties of List<T> which needs to be populated in the CSV files. Header caption is the name of the column for the field in the report.
Sample Report
Customer Name, Address,
ALFKI , 31 Independence Ave., Washington
If you just want to add/remove columns at run time in this one report, it would be even easier to use a plain text file. Store column information in a format you can easily parse ( something like CName|Customer Name). When you need to generate CSV, read all lines, split by | (or whatever separator you choose) and go from there. You will probably also want to add a comment or documentation note somewhere about the format (in case you or someone else need to come back and modify it in a year or more).
XML might become useful if you:
plan to put several reports into one file, and maybe give them names
provide some way for other people to submit their own reports
create some authoring tool to allow people to customize reports
localize column names in CSV. You could define something like
.
<report>
<fields>
<field name="CName">
<header language="en-us">Customer Name</header>
<header language="es-es">Nombre de cliente</header>
...
</field>
...
</fields>
</report>
want to experiment with XML libraries
In those cases XML may be useful because you could define an XSD and easily validate that submitted reports are valid.
I have a problem with respect to XML Serialization. I shall try to explain it with the following example xml file
<AutoExpo>
<Details>
<Venue>XYZ</Venue>
<StartTime>09:00</StartTime>
<EndTime>21:00</EndTime>
</Details>
<Cars>
<Car>
<Company>Chevrolet</Company>
<Model>Cruz</Model>
<Color>Red</Color>
</Car>
<Car>
<Company>Ford</Company>
<Model>Fiesta</Model>
<Color>Blue</Color>
</Car>
</Cars>
</AutoExpo>
Now, when I read this xml file, I deserialize the cars into objects. The car list can be huge. My code uses this objects and can change the properties of some cars. Now what if I want to serialize only those car objects whose properties have changed, back to the xml file and save it so that next time when my code starts it gets the latest state information.
It would be quite difficult to jump around in the XML file changing properties here and there, wherever they have changed. You should just read the whole file into memory, and when you save, write out the whole thing, overwriting the old file.
XML isn't a terrible way of doing this, but as far as I can tell from the question, a SQL Server (or other RDBMS) database would be much more appropriate. You won't have to worry about issues like this, as the DB engine will do that for you.
Although it may not be the best solution, a potentially viable option would be to serialize the edited list to a seperate file and, in code, compare the two files. If there hasn't been any changes to the information the two text files should be identical. If not, you can replace the old file with the new file. The easiest way would be, rather than serialize to a file and read/write it, perhaps send it to a stream and compare them.
When you serialize an object, it generates the entire XML document. So, if you save that to a file, it will overwrite the previous content of the file. Therefore, if you want the resulting file to contain all the cars, including, but not limited to, the modified ones, then you need to serialize the whole thing. If you only serialized the ones that changed, the file would lose all the cars that did not change. If you really do only want to serialize the changed cars, I would suggest creating a new instance of the AutoExpo object and only insert into it the cars that you want to save, then serialize that object with only the partial list.
If you need to just modify a single element in the XML without touching the rest of it because the data is too big, XML is not a good choice. I would suggest a relational database instead. Alternatively, you could store each car as its own XML file and only load and save each one individually as necessary.
You cannot do that with XML. Consider using a relational database. Relational databases have a built-in file space management mechanism allowing doing exactly what you need. You can update single records, add and delete records.
A Jet .mdb database (Access) is a good candidate for the replacement of a XML-File. You can access it via OLEDB with the restriction that the application must be compiled for 32 bit. Access needs not to be installed.
First of all, your entities must have unique identifiers.
<AutoExpo>
<Details>
<Venue>XYZ</Venue>
<StartTime>09:00</StartTime>
<EndTime>21:00</EndTime>
</Details>
<Cars>
<Car id="1">
<Company>Chevrolet</Company>
<Model>Cruz</Model>
<Color>Red</Color>
</Car>
<Car id="2">
<Company>Ford</Company>
<Model>Fiesta</Model>
<Color>Blue</Color>
</Car>
</Cars>
</AutoExpo>
Now you could use XPath to select those nodes that require updates and change their content.
load the document into an XDocument
find a car: document.Element("Car[id=2]")
set the new value: element.Element("Color").Value = "Black"
However, the downside of using a file-based storage remains. You still have to load the whole file into memory and write it back to the hard drive when you're down updating, but you do not have to serialize all Car objects.
I can't think of an easy way to stream the file from hard drive and manipulate it in one go.
I have a Task where I have to read an csv file and write the content into a c# List.
Since the csv file can change its layout (caption/order) in the future I want to use a configuration file for mapping the attributes.
Now I am wondering if there is an example out there so I don't have to reinvent the weel :D
My datasource looks like this (tab stop seperated)
Customer No. Customer Name Created Discount
10215 John Doe 2010-08-25 5050.23
And my class like this:
Class Customer
{
string CustomerNo {get;set;}
string CustomerName {get;set;}
DateTime CreatedOn {get;set;}
decimal Discount {get;set;}
}
Now I want to have an external xml file with the definition so I can modify it at runtime without recompiling the code.
<customermapping mapstoclass="my.namespace.Customer">
<attribute csvcaption="Customer No." mapstoproperty="CustomerNo"
typeof="System.String" required="true">
<attribute csvcaption="Customer Name" mapstoproperty="CustomerName"
typeof="System.String" required="true">
<attribute csvcaption="Created" mapstoproperty="CreatedOn"
typeof="System.DateTime" required="false">
<attribute csvcaption="Discount" mapstoproperty="Discount"
typeof="System.Decimal" required="false">
</customermapping>
At the end of the Day I want to do the following:
(I already can read all the values from the csv file (the first line is the caption and is in a seperate array)
List<Customer> customers =
CreateCustomerList(string[] csvCaptions, string[] csvLines,
"c:\customermapping.xml");
Shouldn't be to complicated but as I said, if someone already did something similar, any examples are welcome.
It looks like you want to reinvent the xsd schema. If you can change the format use the xml and define that rules in the xml.
If you can't change the format or your data is too large to fit nicely in to xml I guess you are on your own. CSV isn't rather an adhoc format I don't think any body cared enough to create a schema validation for it.
You might want to look into using LINQ for this. There is an articles on LINQ to TEXT here:
Tutorial Reading A Text File Using LINQ
LINQ to TEXT and LINQ to CSV
Update: I've re-read your question and I'm no longer sure that using LINQ will really help solve your problem, however I'm leaving the answer here just in case it helps.
If you can at all help it I would put the logic about what columns map onto what properties in code rather than in xml files.