使用正确的 xsd 解析 xml:类型
parse xml with correct xsd: type
我有 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 -->
我如何自动 parse/deserialize 以正确的 .NET 类型 that corresponds 和 xsd 获取 Value
元素的内容:类型(例如 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();
}
试试这个
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;
}
}
}
}
}
假设您只能期望内置类型,您可以创建一个 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()));
我有 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 -->
我如何自动 parse/deserialize 以正确的 .NET 类型 that corresponds 和 xsd 获取 Value
元素的内容:类型(例如 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();
}
试试这个
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;
}
}
}
}
}
假设您只能期望内置类型,您可以创建一个 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()));