XML,这是什么:null或空元素?

12
关于我的另一个问题:XML反序列化空元素? 我从第三方API服务器上获得了这些元素,用于API测试:
<Taxable />
<DefaultPurchasePrice />

我刚意识到自己对于像那样的元素到底代表空对象还是空的概念已经混淆了。

说到对象,它们是一样的,null object通常表示空对象引用,对吧?但是当尝试将XML元素映射到数据字段/值时,它们可能是不同的,即null字符串是空字符串,但对于十进制价格或布尔值,它们是未定义的,等同于空,但不会为null,除非它们被定义为可为空。

同样,我的XmlSerializer的问题在于无法处理转移像那样的空元素。我能否轻松地在我的代码中修复它?还是应该要求人们提供具有明确定义的XML?因为似乎像那样的空XML元素是未定义的:它在这里,但是对于XML元素本身来说,它可以是null或空无所谓?但对于该元素,我的代码需要弄清如何处理,除非我将所有C#类数据字段设置为字符串类型。否则,如果我的代码尝试直接将空或null XML元素映射到某个数据字段,那肯定会失败。

我必须问这个问题,因为我遇到了XML中有很多这些元素,对于那些特殊的元素,我的.NET XML序列化代码需要将那些字段映射为字符串,如果字符串不为空,我就将它们转换为相应的数据类型,否则我将它们设置为null。在进行反序列化之前,我最终删除了那些空元素,因为这样做更容易。但我确实在想:"在我的代码中我到底在做什么?我刚刚删除了空元素还是null元素?因为它们显然是不同的!但编写XML的人认为它们是相同的,因为XML本身没有'null'的概念,有些人认为决定它是否为null或为空是我的责任。但XML确实使你能够以更清晰的方式表示'null'元素
编辑:
在我提出的例子中,这两个元素显然应该是null而不是空元素。XML并没有真正的null概念,但这些元素可以被省略(如果它们为null,则不要将它们放入XML)或使用@svick所提到的更好的表示方法。或在其他情况下,当它们有意义时应该使用空元素。但不适用于Decimal或Boolean。

2
一个空元素标记是有效的XML。你如何解释,null,empty或其他,完全取决于你。 - fpmurphy
1
@fmurphy:那应该是一个答案……我会点赞的。 - Jim Garrison
@fpmurphy,那么它就是一个空元素吗? - Paul L
@pstar:fpmurphy非常清楚。你必须决定,没有标准的解释。 - Jim Garrison
1
XML规范并没有定义数据的语义,这取决于您使用的特定词汇表的规范。如果该规范没有说明此结构的含义,那么是的,它是有歧义的。如果您没有这样的规范,那么您XML中的所有内容都是模棱两可的。 - Michael Kay
显示剩余4条评论
2个回答

17

<Taxable />
<DefaultPurchasePrice />

这是一个空元素,不是null。

它是空的。从语义上讲,与以下相同:

<Taxable></Taxable>
<DefaultPurchasePrice></DefaultPurchasePrice>
XML本身唯一存在的“null”概念是缺少元素。使用XML的语义,您不能指定一个元素并表示它为空。您必须有某种模式(显式模式,例如DTD、XSD或Schematron,或隐式/逻辑模式)来实现这一点。
不过,这并不限制解释XML的应用程序或官方的XML相关技术。例如,XSD具有一个xsi:nil="true"特性。即使您可以将某些模式属性应用于XML,但这些属性并非“纯”XML;它们是由XSD模式提供的附加内容。
这是一个情况,其中XSD可以在基本的XML结构之上构建自己的语义,并添加一个明确的nil,在一个不存在nil的地方。这种灵活性被认为是XML的优点。

另一个很好的解释。几乎每个词都同意。但是,'xsi:nil = 'ture''是Xml模式的内置声明,您可以使用它来表示“null”元素。这有点像说没有任何库,C#就无法做任何事情。但是,再次说明我的XML理解有限:D - Paul L
@pstar:进行了澄清和修正。请告诉我这个版本是更好,更差,还是一样的 :) - Merlyn Morgan-Graham
谢谢,看起来更清晰了。但我现在有一个问题。我不确定xmlns:xsi和XSD之间的关系,我是否必须至少拥有xmlns:xsi才能使用XSD,并因此免费获得xsi:nil和其他一些内置属性? - Paul L
@pstar:是的,你必须添加命名空间别名才能使用它们。这里是一份来自标准推荐文档的描述:http://www.w3.org/TR/xmlschema-1/#Instance_Document_Constructions - Merlyn Morgan-Graham

2

我认为这归结于XML和您喜欢的编程语言的对象模型之间没有默认映射。考虑以下XML:

<Person Name="John">
    <Father>
        <Person Name="Jim" />
    </Father>
    <Mother>
        <Person Name="Jenny" />
    </Mother>
</Person>
< p >“Person”是否有属性(或字段)“Father”和“Mother”?还是“Person”表示一个集合,可以包含类型为“Father”和“Mother”的对象(可能继承自抽象基类型“FamilyMember”)?这在XML中并不清楚,你可以决定如何在对象模型中表示它。(虽然模式的存在在一定程度上改变了这种情况,但仍然存在解释的余地。)

同样,“null”的概念在XML中不存在。另一方面,“空元素”的概念不能直接映射到对象模型中。它们并不相同,空元素仍然可以具有属性,并且它有一个“类型”(元素名称)。

通常,我认为好的解决方案是有一个特殊的XML元素来表示“null”(“<Null />”),但在你的特定情况下,另一种解决方案可能更有意义。


讲解得非常清楚。你在最后一段提到了另一个解决方案是什么? - Paul L
你可以像你提到的那样使用空元素。或者你可以完全省略该属性。或者甚至可以使用类似于 isEmpty="true" 的属性。 - svick
1
实际上,还有另一个很好的解决方案来表示“null”('xsi:nil="true"'),请参见此链接:https://dev59.com/BHRA5IYBdhLWcg3w8ikl。 - Paul L

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接