表示空XML元素的正确方法是什么?


166

我已经看到null以几种方式表示的元素:

该元素存在xsi:nil="true"

 <book>
     <title>Beowulf</title>
     <author xsi:nil="true"/>
 </book>

该元素存在,但表示为一个空元素(我认为这是错误的,因为“空”并且null在语义上有所不同):

 <book>
     <title>Beowulf</title>
     <author/>
 </book>

 <!-- or: -->
 <book>
     <title>Beowulf</title>
     <author></author>
 </book>

返回的标记中根本不存在该元素

 <book>
     <title>Beowulf</title>
 </book>

该元素有一个<null/>子元素(来自下面的TStamper):

 <book>
     <title>Beowulf</title>
     <author><null/></author>
 </book>

是否存在正确或规范的方式来表示这样的null值?除了上述示例,还有其他方法吗?

上面示例的XML是人为设计的,因此请不要过多阅读。:)

Answers:


121

xsi:nil是表示值的正确方法,例如:当发出DOM Level 2调用getElementValue()时,将返回NULL值。xsi:nil也用于指示没有内容的有效元素,即使该元素的内容类型通常不允许空元素。

如果使用了空标签,则getElementValue()返回空字符串(“”)。如果省略该标签,则甚至不存在作者标签。这可能与将其设置为“ nil”在语义上有所不同(例如,将“系列”设置为nil可能是这本书不属于任何系列,而省略系列可能意味着该系列对当前元素不适用。)

来自:W3C

XML模式:结构引入了一种机制,该机制用于发出信号,即使元素的内容类型不需要甚至不允许空内容,但该元素不包含内容时也应将其视为有效。如果元素的属性xsi:nil的值为true,则该元素可能没有内容就是有效的。这样标记的元素必须为空,但如果相应的复杂类型允许,则可以携带属性。

澄清:
如果您有一个book xml元素,而子元素之一是book:series,则在填写它时有几种选择:

  1. 完全删除元素-当您希望指出该系列不适用于这本书或该书不是系列的一部分时,可以这样做。在这种情况下,永远不会调用具有与book:series匹配的模板的xsl转换(或其他基于事件的处理器)。例如,如果您的xsl将book元素变成表格行(xhtml:tr),则使用此方法可能会得到不正确数量的表格单元格(xhtml:td)。
  2. 将元素留空-这可能表示该系列是“”,或者是未知的,或者这本书不是该系列的一部分。任何与book:series匹配的xsl转换(或其他基于Evernt的解析器)都将被调用。current()的值为“”。使用此方法,您将获得与下面描述的相同数量的xhtml:td标签。
  3. 使用xsi:nil =“ true”-这表示book:series元素为NULL,而不仅仅是空。具有模板匹配book:series的xsl转换(或其他基于事件的解析器)将被调用。current()的值将为空(不是空字符串)。此方法与(2)之间的主要区别在于book:series的架构类型不需要允许空字符串(“”)作为有效值。这对于系列元素没有任何实际意义,但是对于在架构中定义为枚举类型的语言元素,xsi:nil =“ true”允许该元素不包含数据。另一个示例是小数类型的元素。如果希望它们为空,则可以联合一个只允许使用“”和小数的枚举字符串,也可以使用可为空的小数。

11
使用xsi:nil是正确的,但是您应该确保它在正确的名称空间中:xmlns:xsi =“ w3.org/2001/XMLSchema-instance
STW

实际上是xmlns:xsi="http://w3.org/2001/XMLSchema-instance"。请注意缺少的http://。这很重要,因为名称空间字符串实际上只是xml解析器的字符串,而不是uri。
Burak Arslan

9
呵呵,我相信还是有点错误。应该是xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"。注意“ www。”。参见w3.org/TR/xmlschema-1/#no-xsi
Janne Mattila

如我在回答中所述,我不同意这种解释,因为它不是元素状态的表示,而是元素使用的限制
Oakcool

2
@ChrisV:不正确,xsi:必须声明前缀。如果您尝试使用xsi:未声明的前缀,那么一个支持名称空间的XML解析器将拒绝您的XML文档。此处的相关规范是w3.org/TR/xml-names/#nsc-NSDeclared(“名称空间约束:已声明前缀”),其中说只有预定义的前缀是xml:xmlns:。XML模式建立在XML名称空间规范的基础上,但不向其添加任何其他预定义的前缀,因为这样做实际上会违反XML名称空间规范。
西蒙·基桑

9

因为XML从根本上没有null概念,所以没有规范的答案。但是我假设您想要Xml / Object映射(因为对象图具有null);因此,答案是“无论工具使用什么”。如果编写处理,则意味着您喜欢什么。对于使用XML Schema的工具而言,这xsi:nil是必经之路。对于大多数映射器,忽略匹配的元素/属性是做到这一点的方法。



7

w3链接中的文档

http://www.w3.org/TR/REC-xml/#sec-starttags

说这是推荐的形式。

<test></test>
<test/>

在另一个答案中提到的属性是验证机制,而不是状态的表示。请参考http://www.w3.org/TR/xmlschema-1/#xsi_nil

XML模式:结构引入了一种机制,机制用于发出信号,即使元素的内容类型不需要甚至不允许空内容,但该元素不包含任何内容时也应将其视为有效。如果元素的属性xsi:nil的值为true,则该元素可能没有内容就有效。这样标记的元素必须为空,但如果相应的复杂类型允许,则可以携带属性。

为了澄清这个答案:内容

  <Book>
    <!--Invalid construct since the element attribute xsi:nil="true" signal that the element must be empty-->
    <BuildAttributes HardCover="true" Glued="true" xsi:nil="true">
      <anotherAttribute name="Color">Blue</anotherAttribute>
    </BuildAttributes>
    <Index></Index>
    <pages>
      <page pageNumber="1">Content</page>            
    </pages>
    <!--Missing ISBN number could be confusing and misguiding since its not present-->
  </Book>
</Books>

7
这是对元素的建议;您是否认为空===空?我相信这两者之间会有差异,尽管通常是视情况而定。如果您声明它们是相同的,我建议您在答案中提及该论点。
罗布·赫鲁斯卡

1
空不等于空;如果是这样,就永远不会问这个stackoverflow问题。这个答案是错误的。但是,程序员应确定将准备读取XML的逻辑是否已准备好处理丢失的元素或xsi:nil;。如果不是,则可能有必要使用以下形式之一;也就是说,可能有必要失去null / missing元素和空元素之间的区别。
制造商史蒂夫(Steve)2015年

@RobHruska是的,您是对的,它是一个空元素的定义,但是如果考虑KitsuneYMG所指向的W3C定义,则它定义该元素必须为null,并且我认为该表示形式更多的是标记,然后表示其当前状态的表示形式,因此我不同意该答案,并认为空是null元素的最佳表示形式。这个想法很简单,要保持良好的结构,您需要将所有元素都表示出来,否则您将不知道它的存在,因此可能会歪曲它。
Oakcool,2015年

4

您可以使用xsi:nil,当你的模式语义指示元素有一个默认值,如果元素不存在应使用默认值。我必须假设有些聪明的人对前面的句子不是一个不言而喻的可怕想法,但这听起来对我来说有九种坏处。我曾经使用的每种XML格式都通过省略元素来表示空值。(或属性,祝您好运xsi:nil


如果在文档发布应用程序中,如果元素没有内容,但您希望标题页上的日期默认为当前日期,则date完全省略元素没有太大帮助,因为应用程序不知道您想要标题页上的位置显示的日期。(如果省略的元素只有一个可能的位置,这不是问题;在实际文档词汇中,几乎所有元素都具有许多可能的位置。)
CM Sperberg-McQueen

4

简单地忽略属性或元素在不太正式的数据中效果很好。

如果您需要更复杂的信息,则GML架构会添加属性nilReason,例如:GeoSciML中

  • xsi:nil 值为“ true”的表示没有可用值
  • nilReason可用于记录缺少值的其他信息;这可能是标准GML原因(missing, inapplicable, withheld, unknown)之一,或以开头的文本other:,也可能是指向更详细说明的URI链接。

交换数据时,通常会使用XML角色,发送给一个收件人的数据或出于给定目的的数据,其内容可能模糊不清,供其他付费或进行其他身份验证的人使用。了解内容丢失的原因可能非常重要。

科学家还担心为什么信息会丢失。例如,如果出于质量原因将其删除,他们可能希望查看原始的不良数据。


2

在许多情况下,Null值的目的是为应用程序的先前版本中不存在的数据值提供服务。

假设您有一个来自应用程序“ ReportMaster”版本1的xml文件。

现在,在ReportMaster版本2中,添加了一些可以定义或不能定义的属性。

如果您使用“无标记表示空”表示形式,则可以自动向后兼容以读取ReportMaster 1 xml文件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.