0

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; }
}
4
  • 1
    you are looking for xml serialization Commented Sep 2, 2014 at 7:55
  • Not really because they have nodes while i'm using mostly attributes. Please i would really appreciate some sample algorithm or tiny code, just to have an idea Commented Sep 2, 2014 at 7:58
  • 1
    that is not valid xml... Commented Sep 2, 2014 at 8:00
  • i fixed the xml file structure, now it's ok, anyways the xml itself is ok Commented Sep 2, 2014 at 8:01

1 Answer 1

4

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; } }
}
Sign up to request clarification or add additional context in comments.

33 Comments

Thank you for your help, could you take a look at my structure of xml? besides, i'm working on visual studio
@AniAni your xml isn't actually xml, but I'll edit in what it does with something based on that. The xsd.exe tool is a freely available part of the .NET sdk
Thanks, but it would be better for me if it'S not a tool, well i wish i could understand it but it's difficult for me
@AniAni you say "I need to build a class that will allow me to read it."; that is exactly and completely what the xsd.exe tool does. I'm not exactly sure what the issue is here... but you can do it by hand too: see the much shorter (but equivalent) hand-coded version at the end.
xsd.exe is the way to go, at least for first step (generation of XSD from XML). You could also try xsd2code.codeplex.com which offers a few more options than xsd.exe for class generation from .xsd file.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.