开发者

Adding XML atttribute to the properties in the class

I need to synchronize b开发者_高级运维etween databases with different fieldnames. I can export records to a xml files from the first database as:

 <Table>
    <Route No="1108">
       <Name No="60">Joe</Name>
       <City No="70">City1</City>
    </Route>
    <Route No="1108">
       <Name No="60">John</Name>
       <City No="70">City2</City>
    </Route>
    <Route No="1108">
       <Name No="60">Jan</Name>
       <City No="70">City4</City>
    </Route>
    <Route No="1108">
       <Name No="60">Jack</Name>
       <City No="70">City6</City>
    </Route>
</Table>

I can serialize this XML file into the second database using the element names Route->Name and City.

But send some data back is the problem. I have declared the class like this:

public class Route
{
    [XmlAttribute]
    public string No 
    { 
        get { return "1108"; } 
    }

    public string Name 
    { 
        get { return _Name; } 
        set { _Name = value; } 
    }

    public string City
    {
        get { return _City; }
        set { _City = value; }
    }
}

I can create this in code easily but for 100 tables it's to much work. I would like to use de/serialize?

I would never expected this to be my show stopper.


You seem to have chosen the wrong tool for the job.

This is a job for SQL Server Integration Services (SSIS). This is exactly what it's good at.


John Saunders is right, XML serialisation is probably not the best tool for the job...

Now, if you still want to go this way, there are two options if you want to add attributes on Name and City:

  • Implement the IXmlSerializable interface, which gives you full control over the XML serialization process. The major drawback is that it's tedious to implement, especially if you must do it for many classes

  • Make classes for Name and City, rather than represent them directly as strings. Since there seems to be a No attribute on all you elements, you might as well make them all inherit from a common base class. You can use the XmlText attribute to serialize a property as the content of an element.

    public abstract class EntityWithNumber
    {
        [XmlAttribute("No")]
        public int Number { get; set; }
    }
    
    public class Name : EntityWithNumber
    {
        [XmlText]
        public string Value { get; set; }
    }
    
    public class City : EntityWithNumber
    {
        [XmlText]
        public string Name { get; set; }
    }
    
    public class Route : EntityWithNumber
    {
        public Name Name { get; set; }
        public City City { get; set; }
    }
    


While setting XMLAttribute attribute you can only add attribute to root XML element.


Actually I think you need something different altogether.

From the snippet you provided, I guess you could deserialize in an object like this:

[Serializable]
[XmlType(AnonymousType=true)]
[XmlRoot(IsNullable=false)]
public partial class Table {

    [XmlElement("Route")]
    public TableRoute[] Items { get; set; }
    }
}

[Serializable]
[XmlType(AnonymousType=true)]
public partial class TableRoute {

    [XmlElement]
    public TableRouteItem[] Name { get; set; }

    [XmlElement]
    public TableRouteItem[] City { get; set; }

    [XmlAttribute]
    public string No { get; set; }
}

[Serializable]
[XmlType(AnonymousType=true)]
public partial class TableRouteItem {

    [XmlAttribute]
    public string No { get; set; }

    [XmlText]
    public string Value { get; set; }
}

The problem with your data is that the columns (or what I guess are columns) there are more than one value per item.


How about this?

public class Route
{
    [XmlAttribute("No")]
    public int Number { get {return "1108";} }

    public Name Name { get; set; }
    public City City { get; set; }
}

public class Name
{
    [XmlAttribute("No")]
    public int Number { get {return "60";} }

    [XmlText]
    public string Value { get; set; }
}

public class City
{
    [XmlAttribute("No")]
    public int Number { get {return "70";} }

    [XmlText]
    public string Name { get; set; }
}


After reading and reading it I came up with this.

1. I added my own attribute class? there must be a smarter way!!

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = true)]
public class XMLAttributeProperty : Attribute
{
    public XMLAttributeProperty(string name, string value)
    {
        this.Name = name;
        Value = value;
    }

    public string Name;
    public string Value;
}

2. Add these attributes to the class properties

public class Route
{
    [XmlAttribute]
    public string No 
    { 
        get { return "1108"; } 
    }

    **[XMLAttributeProperty("No", "60")]**
    public string Name 
    { 
        get { return _Name; } 
        set { _Name = value; } 
    }

    **[XMLAttributeProperty("No", "70")]**
    public string City
    {
        get { return _City; }
        set { _City = value; }
    }
}

3. After the default serializing the class to an element..

 <Table>
    <Route No="1108">
       <Name>Joe</Name>
       <City>City1</City>
    </Route>
</Table>

4. I take over and add the attributes.

foreach (var property in trp.GetType().GetProperties()) //class ->typeof(Transport).GetProperties()
{
    foreach (XMLAttributeProperty att in property.GetCustomAttributes(typeof(XMLAttributeProperty), true).Cast<XMLAttributeProperty>())
    {
        Log.Level0(string.Format("Property {0}, {1}={2}", property.Name, att.Name, att.Value));
        var fieldInElement = el.Descendants(property.Name).FirstOrDefault();
        if (fieldInElement != null)
        {
            try
            {
                fieldInElement.Add(new XAttribute(att.Name, att.Value));
            }
            catch { }
        }
    }
}

5. This is the result. Please comment or show me a better/faster way. Im happy but lost a lot of time.

<Table>
    <Route No="1108">
       <Name No="60">Joe</Name>
       <City No="70">City1</City>
    </Route>
</Table>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜