Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# XML序列化查询_C#_.net_Xml_Serialization_Xml Serialization - Fatal编程技术网

C# XML序列化查询

C# XML序列化查询,c#,.net,xml,serialization,xml-serialization,C#,.net,Xml,Serialization,Xml Serialization,我有以下需要反序列化/序列化的XML: <instance> <dog> <items> <item> <label>Spaniel</label> </item> </items> </dog> <cat> <items> <item>

我有以下需要反序列化/序列化的XML:

<instance>
<dog>
    <items>
        <item>
            <label>Spaniel</label>
        </item>
    </items>
</dog>
<cat>
    <items>
        <item>
            <label>Tabby</label>
        </item>
    </items>
</cat>
</instance>

如果不手动解析XML,我真的不确定从哪里开始。我希望代码尽可能简短。有什么想法吗?(不,我的项目实际上并不涉及猫和狗)。

您可以通过IXmlSerializable接口进行自定义序列化,以获得所需的结构。

一个简单的工作示例(为了简洁起见跳过猫),使用:

使用System.Collections.Generic;
使用System.IO;
使用System.Xml.Serialization;
[XmlRoot(“实例”)]
公营动物{
[XmlElement(“狗”)]
公狗{get;set;}
}
公家犬{
[XmlArray(“项”)]
[XmlArrayItem(“项目”)]
公共列表项=新列表();
}
公共类项目{
[XmlElement(“标签”)]
公共字符串标签{get;set;}
}
班级计划{
静态void Main(参数字符串[]args){
字符串xml=@“
猎犬
";
XmlSerializer XmlSerializer=新的XmlSerializer(typeof(AnimalInstance));
AnimalInstance实例=(AnimalInstance)xmlSerializer.Deserialize(新的StringReader(xml));
}
}

为什么编写自定义解析代码会出现这样的问题?对于您的简单示例,使用XDocument实际上可能需要更少的代码:

XDocument xdoc = XDocument.Parse(xml);
AnimalInstance animal = new AnimalInstance()
{
    Dog = xdoc.XPathSelectElement("instance/dog/items/item/label").Value,
    Cat = xdoc.XPathSelectElement("instance/cat/items/item/label").Value
};

您还可以使用XSL将XML文档转换为您喜欢的结构,并反序列化此转换的输出。但是对于这样一个简单的结构,您应该使用另一个解决方案,如Paolo Tedesco提供的解决方案

如果对创建xml序列化类有疑问,我发现解决问题的最简单方法是:

  • 将所有虚拟数据转储到XML文件中
  • 运行xsd.exe以创建.xsd架构文件
  • 在架构文件上运行xsd.exe以创建类文件
我不久前在一篇博客文章中写了一篇关于它的快速教程:


这只需要不到一分钟的时间,然后你就可以轻松地从那里调整事情。XSD.exe确实是您的朋友

——但我希望有一种更好的方法,不必编写自定义代码来解析XML+顺便说一句,这是我的建议。这次我会选择保罗的答案,因为我需要序列化和反序列化。好建议。我最终使用了几乎所有的类,但我将所有类都嵌套在
animalistance
中,这样它们就不会明显暴露出来。@David Neale:如果你不想让类公开,你可以创建一个序列化程序集,并使用InternalsVisibleToAttribute对其进行赋值:检查这个问题
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

[XmlRoot("instance")]
public class AnimalInstance {
    [XmlElement("dog")]
    public Dog Dog { get; set; }
}

public class Dog {
    [XmlArray("items")]
    [XmlArrayItem("item")]
    public List<Item> Items = new List<Item>();
}

public class Item {
    [XmlElement("label")]
    public string Label { get; set; }
}

class Program {
    static void Main(params string[] args) {
        string xml = @"<instance>
<dog>
    <items>
        <item>
            <label>Spaniel</label>
        </item>
    </items>
</dog>
</instance>";

        XmlSerializer xmlSerializer = new XmlSerializer(typeof(AnimalInstance));
        AnimalInstance instance = (AnimalInstance)xmlSerializer.Deserialize(new StringReader(xml));
    }
}
XDocument xdoc = XDocument.Parse(xml);
AnimalInstance animal = new AnimalInstance()
{
    Dog = xdoc.XPathSelectElement("instance/dog/items/item/label").Value,
    Cat = xdoc.XPathSelectElement("instance/cat/items/item/label").Value
};