使用反射将XML转换为Object

时间:2023-02-12 21:49:32

If you like problems to resolve, here a big one :D

如果你想解决问题,这里有一个很大的问题:D

First, It isn't about serialization, ok?

首先,它不是关于序列化,好吗?

Well, my situation... I am writting a function that I will pass as parameter a Xml (XmlDocument) and an object (Object) as reference. It will return to me a object (object that was referenced) filled with the values from the Xml (XmlDocument).

好吧,我的情况......我正在编写一个函数,我将作为参数传递给Xml(XmlDocument)和一个对象(Object)作为参考。它将返回一个填充了Xml(XmlDocument)中的值的对象(被引用的对象)。

For example:

I have a Xml like:

我有一个Xml像:

<user>
  <id>1</id>
  <name>Daniel</name>
</user>

Also I have my function

我也有我的功能

public Object transformXmlToObject (XmlDocument xml, Object ref)
{
  // Scroll each parameters in Xml and fill the object(ref) using reflection.
  return ref;
}

How will I use it?

我将如何使用它?

I will use like this:

我会用这样的:

[WebMethod]
public XmlDocument RecebeLoteRPS(XmlDocument xml)
{
  // class user receive the object converted from the function
  User user = new User();
  user = transformXmlToObject(xml, user);

  // object filled 
}

I need help guys, please.

我需要帮助的人。

Best regards, Dan

最好的问候,丹

5 个解决方案

#1


1  

Erm, yes, this is exactly about serialization. In fact, this is exactly what XML serialization was written for.

嗯,是的,这正是序列化。实际上,这正是为其编写XML序列化的原因。

Anyway, if you want to write your own, perhaps you can set properties based on the tags in your XML blob? i.e. if you User object has an Id and a Name property, perhaps you should set them in accordance with the XML blob?

无论如何,如果你想自己编写,也许你可以根据XML blob中的标签设置属性?即如果您的User对象具有Id和Name属性,您可能应该根据XML blob设置它们吗?

#2


6  

This should do what you want.

这应该做你想要的。

using System.Xml;
using System.Reflection;
using System.ComponentModel.DataAnnotations;
using System.Collections;

namespace MyProject.Helpers
{
    public class XMLHelper
    {
        public static void HydrateXMLtoObject(object myObject, XmlNode node)
        {
            if (node == null)
            {
                return;
            }

            PropertyInfo propertyInfo;
            IEnumerator list = node.GetEnumerator();
            XmlNode tempNode;

            while (list.MoveNext())
            {
                tempNode = (XmlNode)list.Current;

                propertyInfo = myObject.GetType().GetProperty(tempNode.Name);

                if (propertyInfo != null) {
                    setProperty(myObject,propertyInfo, tempNode.InnerText);

                }
            }
        }
    }
}

#3


1  

If User is an already-defined object with properties to be filled in with the XML data, then yes, this is an XML serialization problem.

如果User是一个已经定义的对象,其属性要用XML数据填充,那么是的,这是一个XML序列化问题。

If you want User to be an object with dynamic structure based at run-time on the XML data, then take a look at ExpandoObject in .NET 4.0. It should be possible to traverse the XML tree and build an equivalent tree of ExpandoObject instances.

如果您希望User在运行时基于XML数据成为具有动态结构的对象,那么请查看.NET 4.0中的ExpandoObject。应该可以遍历XML树并构建一个ExpandoObject实例的等效树。

#4


0  

I agree, this is indeed about Serialization, and should be what you're looking for. However, to pique your interest about querying XML documents the easy way, have a look at LINQ to XML.

我同意,这确实是关于序列化,应该是你正在寻找的。但是,为了激发您对查询XML文档的兴趣,请查看LINQ to XML。

#5


0  

I'll add some type validation in the answer posted by @andyuk. So that for each property, it will lookup the property type and then try to convert the xml value so that no exceptions will be thrown.

我将在@andyuk发布的答案中添加一些类型验证。因此,对于每个属性,它将查找属性类型,然后尝试转换xml值,以便不会抛出任何异常。

But still you need to make sure that xml data should have same type of data which you are inserting as property value. You can do by xsd file for your xml file, or just ignore it if you know about your data and it won't change.

但是仍然需要确保xml数据应该具有相同类型的数据,并将其作为属性值插入。你可以通过xsd文件为你的xml文件做,或者如果你知道你的数据就忽略它,它就不会改变。

                    var pi = entity.GetType( ).GetProperty( eleProperty.Name.LocalName );
                    if ( pi.PropertyType == typeof( DateTime ) )
                    {
                        DateTime val = DateTime.MinValue;
                        DateTime.TryParse( ele.Value, out val );
                        pi.SetValue( entity, val, null );
                    }
                    else if ( pi.PropertyType == typeof( Int32 ) )
                    {
                        int val = 0;
                        Int32.TryParse( eleProperty.Value, out val );
                        pi.SetValue( entity, val, null );
                    }
                    else if ( pi.PropertyType == typeof( bool ) )
                    {
                        bool val = false;
                        Boolean.TryParse( eleProperty.Value, out val );
                        pi.SetValue( entity, val, null );
                    }
                    else
                    {
                        pi.SetValue( entity, eleProperty.Value, null );
                    }

#1


1  

Erm, yes, this is exactly about serialization. In fact, this is exactly what XML serialization was written for.

嗯,是的,这正是序列化。实际上,这正是为其编写XML序列化的原因。

Anyway, if you want to write your own, perhaps you can set properties based on the tags in your XML blob? i.e. if you User object has an Id and a Name property, perhaps you should set them in accordance with the XML blob?

无论如何,如果你想自己编写,也许你可以根据XML blob中的标签设置属性?即如果您的User对象具有Id和Name属性,您可能应该根据XML blob设置它们吗?

#2


6  

This should do what you want.

这应该做你想要的。

using System.Xml;
using System.Reflection;
using System.ComponentModel.DataAnnotations;
using System.Collections;

namespace MyProject.Helpers
{
    public class XMLHelper
    {
        public static void HydrateXMLtoObject(object myObject, XmlNode node)
        {
            if (node == null)
            {
                return;
            }

            PropertyInfo propertyInfo;
            IEnumerator list = node.GetEnumerator();
            XmlNode tempNode;

            while (list.MoveNext())
            {
                tempNode = (XmlNode)list.Current;

                propertyInfo = myObject.GetType().GetProperty(tempNode.Name);

                if (propertyInfo != null) {
                    setProperty(myObject,propertyInfo, tempNode.InnerText);

                }
            }
        }
    }
}

#3


1  

If User is an already-defined object with properties to be filled in with the XML data, then yes, this is an XML serialization problem.

如果User是一个已经定义的对象,其属性要用XML数据填充,那么是的,这是一个XML序列化问题。

If you want User to be an object with dynamic structure based at run-time on the XML data, then take a look at ExpandoObject in .NET 4.0. It should be possible to traverse the XML tree and build an equivalent tree of ExpandoObject instances.

如果您希望User在运行时基于XML数据成为具有动态结构的对象,那么请查看.NET 4.0中的ExpandoObject。应该可以遍历XML树并构建一个ExpandoObject实例的等效树。

#4


0  

I agree, this is indeed about Serialization, and should be what you're looking for. However, to pique your interest about querying XML documents the easy way, have a look at LINQ to XML.

我同意,这确实是关于序列化,应该是你正在寻找的。但是,为了激发您对查询XML文档的兴趣,请查看LINQ to XML。

#5


0  

I'll add some type validation in the answer posted by @andyuk. So that for each property, it will lookup the property type and then try to convert the xml value so that no exceptions will be thrown.

我将在@andyuk发布的答案中添加一些类型验证。因此,对于每个属性,它将查找属性类型,然后尝试转换xml值,以便不会抛出任何异常。

But still you need to make sure that xml data should have same type of data which you are inserting as property value. You can do by xsd file for your xml file, or just ignore it if you know about your data and it won't change.

但是仍然需要确保xml数据应该具有相同类型的数据,并将其作为属性值插入。你可以通过xsd文件为你的xml文件做,或者如果你知道你的数据就忽略它,它就不会改变。

                    var pi = entity.GetType( ).GetProperty( eleProperty.Name.LocalName );
                    if ( pi.PropertyType == typeof( DateTime ) )
                    {
                        DateTime val = DateTime.MinValue;
                        DateTime.TryParse( ele.Value, out val );
                        pi.SetValue( entity, val, null );
                    }
                    else if ( pi.PropertyType == typeof( Int32 ) )
                    {
                        int val = 0;
                        Int32.TryParse( eleProperty.Value, out val );
                        pi.SetValue( entity, val, null );
                    }
                    else if ( pi.PropertyType == typeof( bool ) )
                    {
                        bool val = false;
                        Boolean.TryParse( eleProperty.Value, out val );
                        pi.SetValue( entity, val, null );
                    }
                    else
                    {
                        pi.SetValue( entity, eleProperty.Value, null );
                    }