何时使用元素,何时使用属性[转载]

作者 Uche Ogbuji
采用 XML 的人遇到的老问题是,在 XML 的设计中什么时候使用元素,什么时候使用属性。对于多数设计而言,这个问题很少有绝对的答案,但是开发人员也确实体会到缺乏明确的原则来帮助他们作出决策。本文就什么放在元素中什么放在属性中提供了一些指导原则。

无论使用什么 XML 模式语言,您都需要问这样的问题:
  • 什么时候使用元素,什么时候使用属性来表示信息位?
  • 什么时候需要对元素排队,什么时候不需要考虑顺序?
  • 什么时候需要对类似元素的序列使用包装元素?

根据我和 XML 用户打交道的经验,最常见的还是第一个问题。一些情况下答案是很明确的:

  • 如果涉及到的信息本身能够用元素标记,就把它放在元素中。
  • 如果信息适合采用属性的形式,但可能造成同一元素中有多个同名的属性,则改用子元素。
  • 如果信息需要作为类似标准 DTD 的属性类型,如 IDIDREFENTITY,则使用属性。
  • 如果信息不应该进行空白字符规格化,则使用元素。(XML 处理程序规格化属性的方式可能改变属性值的原始文本。)

不幸的是,设计决策很少能进行这种明确地划分。在灰色的区域中问题仍然是如何进行正确的选择。一般的答案是没有单一正确的答案,取决于您的最佳判断。但这对于那些希望熟悉 XML 的人来说没有多少帮助。事实上,在某些情况下即使专家也不一定意见一致,但是这并不成为不能提供在元素和属性之间选择的一些基本原则的理由。

首先,我想提出曾经听到但建议这样做的两条原则。我曾经听过统统使用元素这样的建议。理由包括属性使事情变得复杂以及属性会影响可扩展性等等不一而足。但是如果不使用属性,就抛弃了 XML 强大功能的一个重要方面,您可能最好是改用某种分隔文本格式。

我也听说过如果是希望在浏览器中显示的那类材料,就使用元素内容。这个原则的问题是鼓励人们根据表示考虑 XML 的内容设计,这两种问题不应混在一起。本文中也提出了一条非常相似的原则,但我是根据内容的用途而不是表示来阐述的。

本文的其他部分将提出一些指导原则,建议在元素和属性之间进行选择时采用。

推荐的指导原则
我把这些指导原则分解成了一些规则,希望能够从总体上说明元素和属性之间的选择。没有哪个规则是绝对的,可以将其作为经验规则使用,如果确实需要完全可以打破这些规则。

核心内容原则
如果认为要处理的信息属于用 XML 表示或传达的基本资料,就将其放在元素中。对于供人阅读的文档一般是指向读者传达的核心内容。对于面向机器的记录格式一般是指直接来自问题域的数据。如果认为该信息对于传递的主要信息而言是外围的或者附属性的,或者单纯用于帮助程序处理传递的主要信息,则使用属性。这样可以避免把核心内容与辅助资料混在一起。对于面向机器的记录格式而言,这一般是指来自问题域主数据上的特定于应用程序的符号。

比如,我曾经看到过许多 XML 格式——通常是业务中自动生成的——文档标题被放在属性中。我认为,像标题这样的文档信息基本组成部分应该作为元素内容。另一方面,我也常常看到这样的情况,内部用的产品标识符被作为元素放在产品的描述记录中。其中的一些情形采用属性更合适,因为特定的内部产品代码不会成为多数读者或者文档处理人员关心的主要目标,尤其是如果 ID 非常长或者采用难以理解的格式。

您也许曾经听说过这样的一条原则,数据使用元素,元数据使用属性。上述两段实际上表达的是同样的原则,只不过使用了更加慎重、更加明确的语言。

结构化信息原则
如果信息用结构化的形式表示,特别是如果这种结构可能需要扩展,则使用元素。另一方面,如果信息用原子记号表示则使用属性。元素是 XML 表示的结构之所以能够扩展的动力源。差不多所有的 XML 处理工具都围绕着这一事实设计,如果能够把结构化信息正确地分解到元素中,您就会发现处理工具可以与您的设计互补,从而提高的生产率并获得了可维护性。属性用于表示元素所表达信息的简单性质。如果违背了 XML 的基本结构,把结构化信息硬塞进属性,可能表面上您似乎获得了简练和便利,但可能要付出维护的代价。

日期是一个很好的例子,它有固定的结构,并且一般作为单个标记,因此作为属性非常合理(更适合用 ISO-8601 表示)。另一方面,我发现在个人姓名的表示中这一原则令设计者感到惊奇。我曾经看到许多放在属性中的姓名,但一直坚持个人姓名应该作为元素的内容。个人姓名有着令人吃惊的可变结构,在一些文化中,如果忽略了尊称或者姓名中各个部分的先后顺序,可能会造成混乱或者冒犯他人。个人姓名也很少作为原子标记,比如有时候会按照名称有时候则按照姓氏排序。还应该指出,如果把整个姓名完全塞进一个元素的内容中或者放在属性中一样会造成问题。因此:

<customer>
  
<name>Gabriel Okara</name>
  
<occupation>Poet</occupation>
</customer>
比下面这种表示强不了多少:
<customer name="Gabriel Okara">
  
<occupation>Poet</occupation>
</customer>

我希望在将来的一篇文章中展开讨论关于姓名的处理。

可读性原则
如果信息是供人们阅读和理解的,则使用元素。一般而言,这一原则是把没有结构的信息放在元素内容中。如果信息主要是方便机器理解和整理,则使用属性。一般来讲,这一原则是指把不是自然语言的信息标记放到属性中。

在一些情况下,人们可以解释所表达的信息但是需要机器正确地使用它们。URL 是一个很好的例子,人们已经学会了在 Web 浏览器或者电子邮件消息中显示的 URL,但是如果没有计算机获取引用的信息,URL 通常没有多少用处。一些数据库标识符也很容易理解(尽管已经建立的数据库管理最佳实践不鼓励使用带有业务意义的 ID),但是这类 ID 通常是机器处理的小道具。基于这些原因,我建议把 URL 和 ID 放在属性中。

元素/属性绑定原则
如果需要根据另一个属性改变它的值则使用元素。XML 在属性和包含它的元素之间建立了非常强的概念联系。属性提供了那个特定元素的一些特性或者修正。XML 处理工具往往都遵循这种概念,让一个属性改变另一个属性通常是可怕的想法。比如,如果要设计一种菜单格式,而且菜单上包括菜量,您可能认为这些信息对一般的菜单格式读者而言并不重要,因此应用核心内容原则将其作为属性。第一种尝试就是这样:

<menu>
  
<menu-item portion="250 mL">
    
<name>Small soft drink</name>
  
</menu-item>
  
<menu-item portion="500 g">
    
<name>Sirloin steak</name>
  
</menu-item>
</menu>

按照结构化信息原则,您决定不把菜量和度量单位放在一个属性中,而是使用一个元素,于是选择以下格式:

<menu>
  
<menu-item portion-size="250" portion-unit="mL">
    
<name>Small soft drink</name>
  
</menu-item>
  
<menu-item portion-size="500" portion-unit="g">
    
<name>Sirloin steak</name>
  
</menu-item>
</menu>

现在属性 portion-unit 修正了 portion-size,而我已经提到这不是一种好主意。元素 menu-item 上的一个属性应该修正那个元素,而不是其他的内容。应该改变这种方案而采用元素:

<menu>
  
<menu-item>
    
<portion unit="mL">250</portion>
    
<name>Small soft drink</name>
  
</menu-item>
  
<menu-item>
    
<portion unit="g">500</portion>
    
<name>Sirloin steak</name>
  
</menu-item>
</menu>

在这个例子中,我结合使用了核心内容原则可读性原则,决定把数量作为元素内容而把度量单位放在属性中。 这是一种不那么固定的情形,其他的方案可能同样合适。这种方案也与最初的决策相抵触,本来按照 核心内容原则 菜量应该放在属性中。这说明有时候这些原则可能得出互相矛盾的结论,您必须根据自己的判断具体情况具体分析。

什么也不能代替学习和实践
XML 设计对于专业人员来说是一个问题,如果要从 XML 中获益就应该有志于研究 XML 的设计原则。许多开发人员承认编写代码能够从精心的设计中获益,但是对于 XML,他们却认为只要看起来能工作就够了。我曾经看到这种区别造成了真正的、痛苦的代价。学习那些合理的 XML 设计所能带给您的经验就是要注意这个问题。对专家设计的标准 XML 词汇表进行分析,记录下您自己的设计决策,评价每个决策在后续设计中的积极和消极影响。一旦取得了经验,您的直觉就会成为做出设计决策的最重要的工具。如果您发现自己在任何重要的领域使用 XML,您的努力也就获得了回报。

 相关内容:
子元素内容对标记属性

posted on 2004-08-16 17:42  9yue  阅读(599)  评论(0编辑  收藏  举报