San*_*hos 3 c# xml xsd linq-to-xml xml-parsing
假设您有一个XML文件:
<experiment
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="experiment.xsd">
<something />
<experiment>
Run Code Online (Sandbox Code Playgroud)
你有xsd文件:
...
<xs:attribute name="hello" type="xs:boolean" use="optional" default="false" />
...
Run Code Online (Sandbox Code Playgroud)
假设属性"hello"是"something"元素的可选属性,默认值设置为"false".
使用XML LINQ的XDocument时,该属性丢失,导致程序在尝试读取时失败:
XDocument xml = XDocument.Load("file.xml");
bool b = bool.Parse(xml.Descendants("something").First().Attribute("hello").Value); // FAIL
Run Code Online (Sandbox Code Playgroud)
LINQ是否自动加载XML模式(来自根元素"experiment"的"xsi:noNamespaceSchemaLocation"属性)或者我是否必须手动强制它?
如何强制LINQ读取可选属性及其默认值?
该Load方法采用XmlReader,如果你使用一个正确的XmlReaderSettings http://msdn.microsoft.com/en-us/library/1xe0740a(即要求验证ValidationType设置为模式并分别关注schemaLocation noNamespaceSchemaLocation与适当的ValidationFlags)然后我认为将使用模式中的默认值创建和填充该属性.
这是一个简短的样本:
XDocument doc;
XmlReaderSettings xrs = new XmlReaderSettings();
xrs.ValidationType = ValidationType.Schema;
xrs.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
using (XmlReader xr = XmlReader.Create("../../XMLFile1.xml", xrs))
{
doc = XDocument.Load(xr);
}
foreach (XElement foo in doc.Root.Elements("foo"))
{
Console.WriteLine("bar: {0}", (bool)foo.Attribute("bar"));
}
Run Code Online (Sandbox Code Playgroud)
带有内容的样本文件
<?xml version="1.0" encoding="utf-8" ?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="XMLSchema1.xsd">
<foo/>
<foo bar="true"/>
<foo bar="false"/>
</root>
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="foo">
<xs:complexType>
<xs:attribute name="bar" use="optional" type="xs:boolean" default="false"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)
输出是
bar: False
bar: True
bar: False
Run Code Online (Sandbox Code Playgroud)