Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LinqToXml未按预期处理可为零的元素_C#_Xml_Xsd_Schema_Linq To Xml - Fatal编程技术网

C# LinqToXml未按预期处理可为零的元素

C# LinqToXml未按预期处理可为零的元素,c#,xml,xsd,schema,linq-to-xml,C#,Xml,Xsd,Schema,Linq To Xml,根据W3C标准,如果您有一个具有nil值的nillable元素,则应该将其格式化如下: <myNillableElement xsi:nil="true" /> …生成的XML是 <myNillableElement /> …这是无效的。而且不仅根据W3C是无效的,根据微软自己的XML/XSD验证器也是无效的。因此,下次验证XML时,会出现错误 我是否遗漏了一些可以正确处理零元素的开关 谢谢。希望这不是一个理想的答案,但我编写了两个扩展方法,至少使处理LinqTo

根据W3C标准,如果您有一个具有nil值的nillable元素,则应该将其格式化如下:

<myNillableElement xsi:nil="true" />
…生成的XML是

<myNillableElement />

…这是无效的。而且不仅根据W3C是无效的,根据微软自己的XML/XSD验证器也是无效的。因此,下次验证XML时,会出现错误

我是否遗漏了一些可以正确处理零元素的开关


谢谢。

希望这不是一个理想的答案,但我编写了两个扩展方法,至少使处理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");

LINQtoXML基本上是不支持模式的——它允许您验证树,但它不会从中派生任何特定的语义。您的错误是认为
null
应该以某种方式始终映射到
xsi:nil
。W3C规范中没有这样的要求(很明显,因为它们不包括任何类型的语言绑定)


特别是,您调用的
XElement
构造函数实际上接受类型为
object[]
的参数,这是一个子类列表-没有理由将
null
传递给该构造函数与
xsi:nil
有任何关联。在任何情况下,LINQ to XML如何知道您正在生成的XML根据某种模式是有效的,并且此模式中的一个特定元素具有
nilled=“true”

您也可以这样做,利用空合并操作符:

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)
    );

非常圆滑!我以前从未遇到过
。我认为扩展方法仍然需要处理
SetElementValue
,因为属性需要添加、删除或保持原样。谢谢你的回答……我想我会编辑文章的标题,因为你让我相信我观察到的并不是真的不正确的行为。不过,如果LinqToXml有一组支持模式的类就好了,这将把空字符串视为null,这可能是不可取的。也就是说,
new-XElement(“Name”,null)
new-XElement(“Name”,null)
都将被标记为
nil
@MattMitchell,有趣的一点,但我想我是这样编码的,因为使用
XElement
表示空元素值是不可能的。即使您执行了
new-XElement(name,null)
Value
属性也将是
string.Empty
,而不是
null
。因此,对于字符串,您确实失去了区分空值和空值的能力,但至少值类型(如
int
)可以按预期工作。如果您能想到字符串的解决方法,请让我知道。对于
.SetNillableElementValue
的情况,您可以检查提供的
值是否为
null
,如果是,请添加nillable属性。正如您所说,在事实之后(例如在
MakeNillable
案例中),无法确定源值是否为null。
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)
    );