Reputation: 25
First of all, i'm sorry, i know my question will be very basic and stuff but please i would really appreciate some help, i'm under lots of pressure, so making smart comments and being ironic wouldn't help
I have this code: At least i'm trying. I have this xml file, i need to save all it's attributes in a class so i can just duplicate it whenever i need to.
I don't know how to.
public static void firstFileXml(string sXml1)
{
var root = XElement.Load(@"sXml1");
var controlElementsFirst = root.Descendants("books");
}
The XML file has attributes like: label, text, label_w etc. I need a function or somethign that will allow me to enter like: explore(xmlLocation) and to do the rest. Because i need to do it for a few xml files
I need to build a class that will allow me to read it. Suppose i have this file of xml:
WAS
<books>
<book label='' page='' intro =''/>
<book label='' page='' intro =''/>
<book label='' page='' intro =''/>
</books>
IS
<SHEET>
<books>
<book label='1' page='1' intro='1'/>
<book label='2' page='2' intro='2'/>
<book label='3' page='3' intro='3'/>
</books>
</SHEET>
And so on. I need first to read this xml file then store the book attributes in a class, so i can use it for hundreds of books later
Code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
static class Program
{
static void Main()
{
// get the xml as a string; note that we could also use
// Deserialize(Stream) to process a FileStream, but this
// works fine
string xml = File.ReadAllText(@"C:\Users\books.xml");
var ser = new XmlSerializer(typeof(BookRoot));
var root = (BookRoot)ser.Deserialize(new StringReader(xml));
foreach (var book in root.Books)
{
Console.WriteLine("label: " + book.Label);
Console.WriteLine("page: " + book.Page);
Console.WriteLine("intro: " + book.Intro);
Console.ReadLine();
}
}
}
[XmlRoot("SHEET")]
public class BookRoot
{
private readonly List<Book> books = new List<Book>();
[XmlArray("books"), XmlArrayItem("book")]
public List<Book> Books { get { return books; } }
}
public class Book
{
[XmlAttribute("label")]
public string Label { get; set; }
[XmlAttribute("page")]
public string Page { get; set; }
[XmlAttribute("intro")]
public string Intro { get; set; }
}
Upvotes: 0
Views: 605
Reputation: 1062512
At the command line:
xsd yourfile.xml
xsd /c yourfile.xsd
This will create C# classes using the xml as a template (via schema inference); you can then use those classes with XmlSerializer
, i.e.
var ser = new XmlSerializer(typeof(YourRootType));
YourRootType root = (YourRootType)ser.Deserialize(source);
Console.WriteLine(root.Foo);
foreach(Bar bar in root.Bars) {
Console.WriteLine(bar.Name);
Console.WriteLine(bar.Id);
}
For example, with:
<books>
<book label='' page='' intro=''/>
<book label='' page='' intro=''/>
<book label='' page='' intro=''/>
</books>
this generates the schema:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="books" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="books" msdata:IsDataSet="true" msdata:Locale="en-US">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="book">
<xs:complexType>
<xs:attribute name="label" type="xs:string" />
<xs:attribute name="page" type="xs:string" />
<xs:attribute name="intro" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
and then the C# code:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34014
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System.Xml.Serialization;
//
// This source code was auto-generated by xsd, Version=4.0.30319.18020.
//
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.18020")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class books {
private booksBook[] itemsField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("book", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public booksBook[] Items {
get {
return this.itemsField;
}
set {
this.itemsField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.18020")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class booksBook {
private string labelField;
private string pageField;
private string introField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string label {
get {
return this.labelField;
}
set {
this.labelField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string page {
get {
return this.pageField;
}
set {
this.pageField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string intro {
get {
return this.introField;
}
set {
this.introField = value;
}
}
}
which works fine with XmlSerializer
, and will correctly deserialize your data, for example:
var ser = new XmlSerializer(typeof(books));
var root = (books)ser.Deserialize(new StringReader(xml));
foreach(var book in root.Items)
{
Console.WriteLine("label: " + book.label);
Console.WriteLine("page: " + book.page);
Console.WriteLine("intro: " + book.intro);
}
Note that you could do it by hand a lot easier:
[XmlRoot("books")]
public class BookRoot {
private readonly List<Book> books = new List<Book>();
[XmlElement("book")]
public List<Book> Books { get { return books; } }
}
public class Book {
[XmlAttribute("label")]
public string Label {get;set;}
[XmlAttribute("page")]
public string Page {get;set;}
[XmlAttribute("intro")]
public string Intro {get;set;}
}
for example:
var ser = new XmlSerializer(typeof(BookRoot));
var root = (BookRoot)ser.Deserialize(new StringReader(xml));
foreach(var book in root.Books)
{
Console.WriteLine("label: " + book.Label);
Console.WriteLine("page: " + book.Page);
Console.WriteLine("intro: " + book.Intro);
}
With the most recent edit that adds a level into the XML, the attributes need tweaking a bit - to change the root element name, and to add an additional level (books/book
=> SHEET/books/book
):
[XmlRoot("SHEET")]
public class BookRoot
{
private readonly List<Book> books = new List<Book>();
[XmlArray("books"), XmlArrayItem("book")]
public List<Book> Books { get { return books; } }
}
Upvotes: 4