1

There is an xml file:

<xmlRoot>
  <properties>
    <property id = "p45663">property title</property>
    <property id = "p00765">property title</property>
    <property id = "p10431">property title</property>
    <property id = "p08332">property title</property>
    <property id = "p00005">property title</property>         
  </properies>
  <items>
    <item id = "111222">
      <p00001>some value</p00001>
      <p22345>some value</p22345>
      <p05589>some value</p05589>
    </item>
    <item id = "333444">
      <p99323>some value</p99323>
      <p03345>some value</p03345>
      <p07741>some value</p07741>
    </item>
    <item id = "555666">
      <p49113>some value</p49113>
      <p03345>some value</p03345>
      <p00532>some value</p00532>
    </item>
  </items>
</xmlRoot>

Total ~5000 properties, ~100000 items in XML. About 15-20 various properties per each item. In each item its own set of properties. Name of the each node in item is a property id.

How can i deserialize it into something like this?

public class xmlDoc
{
  [XmlAttribute("id")]
  public string id { get; set; }
  public List<xmlProp> properties { get; set; }
}

public class xmlProp
{
  public string propertyID { get; set; }
  public string propertyValue { get; set; }
}

I'll be grateful for any help. Thanks.

eXcelsior
  • 15
  • 4
  • 1
    `XmlSerializer` isn't designed for scenarios where the element/attribute names are non-deterministic. In your case, `` etc will be very hard to process via `XmlSerializer`. Do you need to handle the item data? – Marc Gravell Feb 28 '18 at 00:25
  • This is xml with product descriptions. Yes, I need to process the name of each property (the name of the node in this case) and its value. – eXcelsior Feb 28 '18 at 00:27
  • Alternative idea, You can convert it to the xml that can be deserialized to the class above using `XSLT`. Like `Xml->process(xslt)->SerializedXml->process(Deserialized to object)`. You just need to first serialized the class above to see how the `Serialized Xml` should look and craft the `Xslt` according to it. – Vinod Srivastav Feb 28 '18 at 12:16

2 Answers2

0

You can try using the xsd.exe tool that comes with visual studio installation. Please convert the XML to XSD and then XSD to a CS class. Its a command line tool. Please refer to this for the location of the tool. Use the below Commands:

xsd myFile.xml /outputdir:myOutputDir (to get the xsd file)

xsd your.xsd /classes (to get your cs class).

Below is the code I generated for your xml file:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     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.6.1055.0.
// 


/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[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 xmlRoot {

    private object[] itemsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("items", typeof(xmlRootItems), Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    [System.Xml.Serialization.XmlElementAttribute("properties", typeof(xmlRootProperties), Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public object[] Items {
        get {
            return this.itemsField;
        }
        set {
            this.itemsField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class xmlRootItems {

    private xmlRootItemsItem[] itemField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("item", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public xmlRootItemsItem[] item {
        get {
            return this.itemField;
        }
        set {
            this.itemField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class xmlRootItemsItem {

    private string p49113Field;

    private string p99323Field;

    private string p03345Field;

    private string p00532Field;

    private string p07741Field;

    private string p00001Field;

    private string p22345Field;

    private string p05589Field;

    private string idField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string p49113 {
        get {
            return this.p49113Field;
        }
        set {
            this.p49113Field = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string p99323 {
        get {
            return this.p99323Field;
        }
        set {
            this.p99323Field = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string p03345 {
        get {
            return this.p03345Field;
        }
        set {
            this.p03345Field = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string p00532 {
        get {
            return this.p00532Field;
        }
        set {
            this.p00532Field = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string p07741 {
        get {
            return this.p07741Field;
        }
        set {
            this.p07741Field = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string p00001 {
        get {
            return this.p00001Field;
        }
        set {
            this.p00001Field = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string p22345 {
        get {
            return this.p22345Field;
        }
        set {
            this.p22345Field = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string p05589 {
        get {
            return this.p05589Field;
        }
        set {
            this.p05589Field = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string id {
        get {
            return this.idField;
        }
        set {
            this.idField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class xmlRootProperties {

    private xmlRootPropertiesProperty[] propertyField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("property", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)]
    public xmlRootPropertiesProperty[] property {
        get {
            return this.propertyField;
        }
        set {
            this.propertyField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class xmlRootPropertiesProperty {

    private string idField;

    private string valueField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string id {
        get {
            return this.idField;
        }
        set {
            this.idField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlTextAttribute()]
    public string Value {
        get {
            return this.valueField;
        }
        set {
            this.valueField = value;
        }
    }
}
Kiran Rani
  • 154
  • 1
  • 9
0

I like using Dictionary along with the xml linq

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication25
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
       static void Main(string[] args)
        {
           XDocument doc = XDocument.Load(FILENAME);
           XmlDoc xmlDoc = new XmlDoc(doc.Root);


        }
    }
    public class XmlDoc
    {
        public Dictionary<string,string> properties { get; set; }
        public Dictionary<string, Dictionary<string,string>> items { get; set; }

        public XmlDoc(XElement root)
        {
            properties = root.Descendants("property")
                .GroupBy(x => (string)x.Attribute("id"), y => (string)y)
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());
            items = root.Descendants("item")
                .GroupBy(x => (string)x.Attribute("id"), y =>
                    y.Elements().GroupBy(a => a.Name.LocalName, b => (string)b)
                    .ToDictionary(a => a.Key, b => b.FirstOrDefault()))
                    .ToDictionary(x => x.Key, y => y.First());


        }
    }


}
jdweng
  • 33,250
  • 2
  • 15
  • 20