C# 处理-元素xsi:nil与no元素
在C#中,当处理包含在模式中定义为C# 处理-元素xsi:nil与no元素,c#,xml,xml-nil,C#,Xml,Xml Nil,在C#中,当处理包含在模式中定义为nillable=“true”和minOccurs=“0”的元素的XML时,区分nil元素和省略元素的最优雅的解决方案是什么 用例是这样一种情况:服务接收到一个XML片段,其中包含表示已更改的记录的所有字段的元素,但没有一个字段未更改 例如,当记录从{a:1;b:2;c:3;}更改为{a:1;b:4;c:null}时,服务可能会收到: <change> <b>4</b> <c xsi:nil="true" /&g
nillable=“true”
和minOccurs=“0”
的元素的XML时,区分nil元素和省略元素的最优雅的解决方案是什么
用例是这样一种情况:服务接收到一个XML片段,其中包含表示已更改的记录的所有字段的元素,但没有一个字段未更改
例如,当记录从{a:1;b:2;c:3;}
更改为{a:1;b:4;c:null}
时,服务可能会收到:
<change>
<b>4</b>
<c xsi:nil="true" />
</change>
<change>
<b>4</b>
</change>
然而,在C#中,这两个具有不同含义的片段都映射到一个看起来像{a:null;b:4;C:null;}
的对象。解析XML时,有关c显式为零或不存在的信息将丢失。我们不确定a和b是应该设置为null,还是保持不变
在本例中,您可能会建议消息应该包含所有字段以避免混淆(以及识别正在更改的记录的内容),但我们处理的是有关大型记录的实际消息,其中只需要发送实际的字段是相关的。我们处理的不仅仅是整型字段,还有各种简单和复杂的类型
我认为XML片段是相当优雅和清晰的,但是在C语言应用程序中处理它们时,你会建议的最优雅和清晰的解决方案是什么?
使用LINQ到XML,你可以解析字符串/流/文件,并确定元素节点是否包含一个值。
XElement change = XElement.Parse(string); // .Load(stream or file)
var changes = change.Elements()
.Where(x => (string)x != null)
// The above Where() determines your empty from non-empty
.Select(x =>
{
Name = x.Name.LocalName,
Value = (string)x
})
.ToList();
假设您使用的是
XmlSerializer
,则可以添加一个额外的布尔属性来记住是否已显式设置属性。此外,如果属性具有指定的名称XXX
,其中XXX
是相关“真实”属性的名称,则XmlSerializer
将忽略序列化时的属性。例如:
public class TestClass
{
string _value = null;
[XmlElement("Value", IsNullable=true)]
public string Value
{
get { return _value; }
set
{
_value = value;
ValueSpecified = true;
}
}
[XmlIgnore]
public bool ValueSpecified { get; set; }
public static void Test()
{
Test(new TestClass());
Test(new TestClass() { Value = null });
Test(new TestClass() { Value = "Something" });
}
static void Test(TestClass test)
{
var xml = test.GetXml();
Debug.WriteLine(xml);
var testBack = xml.LoadFromXML<TestClass>();
Debug.Assert(testBack.Value == test.Value && testBack.ValueSpecified == test.ValueSpecified);
}
}
公共类TestClass
{
字符串_值=null;
[XmlElement(“值”,IsNullable=true)]
公共字符串值
{
获取{返回_值;}
设置
{
_价值=价值;
指定值=真;
}
}
[XmlIgnore]
指定的公共bool值{get;set;}
公共静态无效测试()
{
Test(新的TestClass());
测试(新的TestClass(){Value=null});
测试(newtestclass(){Value=“Something”});
}
静态无效测试(TestClass测试)
{
var xml=test.GetXml();
Debug.WriteLine(xml);
var testBack=xml.LoadFromXML();
Assert(testBack.Value==test.Value&&testBack.ValueSpecified==test.ValueSpecified);
}
}
三个测试用例的XML输出为:
某物
如您所见,null属性和unset属性之间的区别已成功序列化和反序列化
有关详细信息,请参见此处:。(文档描述了对公共字段的支持,但该功能也适用于公共属性。)我没有在您的帖子中看到您的
minOccurs=0
,您能给出一个示例及其代表的内容吗?
<TestClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
<TestClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Value xsi:nil="true" />
</TestClass>
<TestClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Value>Something</Value>
</TestClass>