根据W3C标准,如果你有一个nil值的nillable元素,你应该像这样格式化:
<myNillableElement xsi:nil="true" />
但是如果你使用这个LinqToXml语句......
element.Add(
new XElement(ns + "myNillableElement", null);
......生成的XML是......
<myNillableElement />
......这是无效的。根据W3C,不仅无效,根据微软自己的XML / XSD验证器无效。因此,下次验证XML时,会出现错误。
我是否遗漏了一些能够正确处理可支付元素的开关?
感谢。
答案 0 :(得分:3)
LINQ to XML主要不支持模式 - 它允许您验证树,但它不会从中获取任何特定的语义。你的错误是相信null
应该总是映射到xsi:nil
。 W3C规范中没有这样的要求(很明显,因为它们不包括任何类型的语言绑定)。
特别是,您调用的XElement
构造函数实际上采用类型为object[]
的参数,这是一个子列表 - 没有理由将null
传递给它应该具有任何相关性到xsi:nil
。在任何情况下,LINQ to XML如何知道您根据某些模式生成有效的XML,并且此模式中的一个特定元素具有nilled="true"
?
答案 1 :(得分:2)
你也可以做这样的事情,利用空合并运算符:
public static object Nil
{
get
{
// **I took a guess at the syntax here - you should double check.**
return new XAttribute(Xsi + "nil", true);
}
}
// ......
object nullableContent = ...;
element.Add(
new XElement(NS + "myNillableElement", nullableContent ?? Nil)
);
答案 2 :(得分:1)
希望这不是理想的答案,但我写了几个扩展方法,至少可以让它更容易处理LinqToXml中的nillable元素。
扩展方法:
public static class XElementExtensions
{
private static XName _nillableAttributeName = "{http://www.w3.org/2001/XMLSchema-instance}nil";
public static void SetNillableElementValue(this XElement parentElement, XName elementName, object value)
{
parentElement.SetElementValue(elementName, value);
parentElement.Element(elementName).MakeNillable();
}
public static XElement MakeNillable(this XElement element)
{
var hasNillableAttribute = element.Attribute(_nillableAttributeName) != null;
if (string.IsNullOrEmpty(element.Value))
{
if (!hasNillableAttribute)
element.Add(new XAttribute(_nillableAttributeName, true));
}
else
{
if (hasNillableAttribute)
element.Attribute(_nillableAttributeName).Remove();
}
return element;
}
}
使用示例
// "nil" attribute will be added
element.Add(
new XElement(NS + "myNillableElement", null)
.MakeNillable();
// no attribute will be added
element.Add(
new XElement(NS + "myNillableElement", "non-null string")
.MakeNillable();
// "nil" attribute will be added (if not already present)
element.SetNillableElementValue(NS + "myNillableElement", null);
// no attribute will be added (and will be removed if necessary)
element.SetNillableElementValue(NS + "myNillableElement", "non-null string");