使用正确的xsd:类型解析XML
本文关键字:类型 XML xsd | 更新日期: 2023-09-27 18:03:51
我有一个包含如下元素的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 -->
我如何自动解析/反序列化这在一种方式,我得到Value
元素的内容在正确的。net类型对应于xsd:类型(例如System.Int16
, System.String
, System.Boolean
)?
这是我尝试过的,但它有点脆弱,必须有一个内置的方法在所有这些。net XML api。
foreach (var value in XDocument.Load(new StreamReader(@"c:'bar.xml")).Descendants("Value"))
{
var actualValue = GetValue(value);
}
...
// TODO: Get rid of this hand written method, .NET should do this for me
private static object GetValue(XElement value)
{
XNamespace ns = "http://www.w3.org/2001/XMLSchema-instance";
var type = value.Attributes(ns + "type").Single().Value;
switch (type)
{
case "xsd:short":
return (short)value;
case "xsd:boolean":
return (bool)value;
case "xsd:string":
return (string)value;
...
}
throw new UnknownTypeException();
}
假设只能使用内置类型,则可以创建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()));
试试这个
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;
}
}
}
}
}