C# 使用正确的xsd:type解析xml

C# 使用正确的xsd:type解析xml,c#,xml,linq-to-xml,xmldocument,xmlreader,C#,Xml,Linq To Xml,Xmldocument,Xmlreader,我有包含如下元素的XML <Value xsi:type="xsd:short">0</Value> <Value xsi:type="xsd:string">foo</Value> <Value xsi:type="xsd:boolean">false</Value> <!-- ... many other types --> 试试这个 using System; using System.Collectio

我有包含如下元素的XML

<Value xsi:type="xsd:short">0</Value>
<Value xsi:type="xsd:string">foo</Value>
<Value xsi:type="xsd:boolean">false</Value>
<!-- ... many other types -->
试试这个

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

namespace ConsoleApplication11
{
    class Program
    {
        static void Main(string[] args)
        {
            List<object> values = new List<object>();
            string xml =
                "<Root xmlns:xsi = \"abc\">" +
                    "<Value xsi:type=\"xsd:short\">0</Value>" +
                    "<Value xsi:type=\"xsd:string\">foo</Value>" +
                    "<Value xsi:type=\"xsd:boolean\">false</Value>" +
                "</Root>";
            XElement root = XElement.Parse(xml);
            XNamespace ns = root.GetDefaultNamespace();
            foreach(XElement value in root.Descendants("Value"))
            {
                string _type = (string)value.Attributes().Where(x => x.Name.LocalName == "type").FirstOrDefault();
                switch (_type)
                {
                    case "xsd:short"  :
                        values.Add((short)value);
                        break;
                    case "xsd:string":
                        values.Add((string)value);
                        break;
                    case "xsd:boolean":
                        values.Add((Boolean)value);
                        break;
                }

            }

        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
命名空间控制台应用程序11
{
班级计划
{
静态void Main(字符串[]参数)
{
列表值=新列表();
字符串xml=
"" +
"0" +
“福”+
“假”+
"";
XElement root=XElement.Parse(xml);
XNamespace ns=root.GetDefaultNamespace();
foreach(root.substands中的XElement值(“值”))
{
string _type=(string)value.Attributes()。其中(x=>x.Name.LocalName==“type”).FirstOrDefault();
开关(U型)
{
案例“xsd:short”:
值。添加((短)值);
打破
案例“xsd:string”:
添加((字符串)值);
打破
案例“xsd:boolean”:
添加((布尔)值);
打破
}
}
}
}
}

假设只能使用内置类型,则可以创建XML序列化程序来反序列化值。幸运的是,您的属性名称与预期的名称匹配,因此不需要执行任何转换

XNamespace xsd = "http://www.w3.org/2001/XMLSchema";
XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
var doc = new XDocument(
    new XElement("root",
        new XAttribute(XNamespace.Xmlns + "xsd", xsd),
        new XAttribute(XNamespace.Xmlns + "xsi", xsi),
        new XElement("Value", new XAttribute(xsi + "type", "xsd:short"), (short)0),
        new XElement("Value", new XAttribute(xsi + "type", "xsd:string"), "foo"),
        new XElement("Value", new XAttribute(xsi + "type", "xsd:boolean"), false)
    )
);

var serializer = new XmlSerializer(typeof(object), new XmlRootAttribute("Value"));
var values = doc.Descendants("Value")
    .Select(v => serializer.Deserialize(v.CreateReader()));

这与我的解决方案有何不同?我的解决方案已经奏效了。由于switch语句,我想完全摆脱
GetValue
方法。你只是内联了那个方法。
XNamespace xsd = "http://www.w3.org/2001/XMLSchema";
XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
var doc = new XDocument(
    new XElement("root",
        new XAttribute(XNamespace.Xmlns + "xsd", xsd),
        new XAttribute(XNamespace.Xmlns + "xsi", xsi),
        new XElement("Value", new XAttribute(xsi + "type", "xsd:short"), (short)0),
        new XElement("Value", new XAttribute(xsi + "type", "xsd:string"), "foo"),
        new XElement("Value", new XAttribute(xsi + "type", "xsd:boolean"), false)
    )
);

var serializer = new XmlSerializer(typeof(object), new XmlRootAttribute("Value"));
var values = doc.Descendants("Value")
    .Select(v => serializer.Deserialize(v.CreateReader()));