我通过套接字接收XML字符串,并希望将这些转换为c#对象。

这些消息的形式是:

<msg>
   <id>1</id>
   <action>stop</action>
</msg>

如何做到这一点呢?


当前回答

简化达米安的回答,

public static T ParseXml<T>(this string value) where T : class
{
    var xmlSerializer = new XmlSerializer(typeof(T));
    using (var textReader = new StringReader(value))
    {
        return (T) xmlSerializer.Deserialize(textReader);
    }
}

其他回答

创建一个DTO作为CustomObject

使用下面的方法使用JAXB将XML字符串转换为DTO

private static CustomObject getCustomObject(final String ruleStr) {
    CustomObject customObject = null;
    try {
        JAXBContext jaxbContext = JAXBContext.newInstance(CustomObject.class);
        final StringReader reader = new StringReader(ruleStr);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        customObject = (CustomObject) jaxbUnmarshaller.unmarshal(reader);
    } catch (JAXBException e) {
        LOGGER.info("getCustomObject parse error: ", e);
    }
    return customObject;
}

我知道这个问题很老了,但我无意中发现了它,我有一个和其他人不同的答案:-)

通常的方法(如上面的评论者所述)是生成一个类并反序列化xml。

但是(警告:这里是无耻的自我推销)我刚刚发布了一个小包,在这里,你不必使用它。你只要说:

string xml = System.IO.File.ReadAllText(@"C:\test\books.xml");
var book = Dandraka.XmlUtilities.XmlSlurper.ParseText(xml);

这就是它的字面意思,没有其他需要。最重要的是,如果xml发生变化,对象也会自动发生变化。

如果您喜欢直接下载dll, github页面在这里。

你需要使用xsd.exe工具,它会被安装到一个类似于Windows SDK的目录中:

C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin

在64位计算机上:

C:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\bin

在Windows 10电脑上:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin

在第一次运行时,您使用XSD .exe并将示例XML转换为XSD文件(XML模式文件):

xsd yourfile.xml

这会给你你的文件。在第二步中,您可以再次使用xsd.exe将其转换为c#类:

xsd yourfile.xsd /c

这应该会给你一个文件yourfile.cs,它将包含一个c#类,你可以使用它来反序列化你得到的XML文件-类似于:

XmlSerializer serializer = new XmlSerializer(typeof(msg));
msg resultingMessage = (msg)serializer.Deserialize(new XmlTextReader("yourfile.xml"));

在大多数情况下都能很好地工作。

更新:XML序列化器将接受任何流作为它的输入-文件或内存流都可以:

XmlSerializer serializer = new XmlSerializer(typeof(msg));
MemoryStream memStream = new MemoryStream(Encoding.UTF8.GetBytes(inputString));
msg resultingMessage = (msg)serializer.Deserialize(memStream);

或者使用StringReader:

XmlSerializer serializer = new XmlSerializer(typeof(msg));
StringReader rdr = new StringReader(inputString);
msg resultingMessage = (msg)serializer.Deserialize(rdr);
public string Serialize<T>(T settings)
{
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    StringWriter outStream = new StringWriter();
    serializer.Serialize(outStream, settings);
    return outStream.ToString();
}

尝试此方法将Xml转换为对象。它正是为你正在做的事情而做的:

protected T FromXml<T>(String xml)
{
    T returnedXmlClass = default(T);

    try
    {
        using (TextReader reader = new StringReader(xml))
        {
            try
            {
                returnedXmlClass = 
                    (T)new XmlSerializer(typeof(T)).Deserialize(reader);
            }
            catch (InvalidOperationException)
            {
                // String passed is not XML, simply return defaultXmlClass
            }
        }
    }
    catch (Exception ex)
    {
    }

    return returnedXmlClass ;        
}

使用下面的代码调用它:

YourStrongTypedEntity entity = FromXml<YourStrongTypedEntity>(YourMsgString);