XML属性 vs 元素

70

何时应使用XML属性,何时应使用XML元素?

例如:

<customData>
  <records>
    <record name="foo" description="bar" />
  </records>
</customData>
或者
<customData>
  <records>
    <record>
      <name>foo</name>
      <description>bar</description>
    </record>
  </records>
</customData>

你应该使用转义后的 < 和 > 来放置标签。 - workmad3
10个回答

38
在IBM的网站上有一篇名为“XML设计原则:何时使用元素与属性”的文章。
尽管似乎没有太多硬性规定,但该文章提到了一些好的指导方针。例如,其中一个建议是,在数据必须不被规范化为空格时使用元素,因为XML处理器可以规范化属性中的数据,从而修改原始文本。
我发现自己不时地参考这篇文章,因为我正在开发各种XML结构。希望这对其他人也有所帮助。
编辑-来自该网站:
核心内容原则
如果您认为问题中的信息是表达或传达在XML中所述的基本材料的一部分,请将其放入元素中。对于可读性较强的文档,这通常意味着向读者传达的核心内容。对于面向机器的记录格式,这通常意味着直接来自问题域的数据。如果您认为该信息对于主要通信是次要或附带的,或者纯粹旨在帮助应用程序处理主要通信,请使用属性。这避免了将辅助材料混杂在核心内容中。对于面向机器的记录格式,这通常意味着来自问题域的主要数据上的应用程序特定符号。
作为一个例子,我看过许多XML格式(通常是企业内部自行制定的),在这些格式中,文档标题通常会被放置在属性中。我认为,标题是文档传达信息的基本组成部分,因此应该始终放在元素内容中。另一方面,我经常看到产品描述记录中将内部产品标识符作为元素抛出的情况。在其中一些情况下,属性更加合适,因为对于大多数读者或文档处理器来说,特定的内部产品代码可能并不是主要关注的内容,尤其是当ID采用非常长或晦涩难懂的格式时。

你可能听说过“数据放在元素中,元数据放在属性中”的原则。以上两段话实际上表达了同样的原则,但使用的语言更加准确和明确。

结构化信息的原则

如果信息以结构化形式表示,特别是当这种结构可以扩展时,则应该使用元素。另一方面,如果信息表示为原子令牌,则应该使用属性。元素是在XML中表示结构的可扩展引擎。几乎所有的XML处理工具都是围绕这个事实设计的,如果将结构化信息正确地拆分成元素,则可以发现处理工具与设计相互补充,从而提高生产力和可维护性。属性是为了表示元素中信息的简单属性而设计的。如果通过将结构化信息强行塞入属性中来违反XML的基本架构,则可能会获得一些表面上的简洁和方便,但你可能需要付出更高的维护成本。

日期是一个很好的例子:日期有固定的结构,通常作为单个令牌使用,因此作为属性是有意义的(最好用 ISO-8601 表示)。另一方面,代表个人姓名则是一个案例,这个原则会让设计师感到惊讶。我经常在属性中看到姓名,但我一直认为个人姓名应该在元素内容中。个人姓名具有令人惊讶的可变结构(在某些文化中,省略尊称或假设名称部分的顺序可能会引起混淆或冒犯)。个人姓名也很少是一个原子令牌。例如,有时您可能想按名字搜索或排序,有时又想按姓氏搜索或排序。我应该指出,把一个完整的姓名塞进单个元素的内容中,和把它放在属性中一样有问题。

22
请问需要翻译的内容是什么语言?如果需要翻译成中文,那么“good guidelines”的具体指什么呢?谢谢! - Kenny Evitt

18

较好的元素与属性争论来自于UK GovTalk指南。该指南定义了用于政府相关XML交换的建模技术,但它本身也非常值得考虑。

必须设计模式,使得元素是XML实例中信息内容的主要持有者。属性更适合于持有附属元数据 - 提供有关元素内容的更多信息的简单项目。在可能导致歧义的情况下,不得使用属性来限定其他属性。

与元素不同,属性无法保存结构化数据。因此,首选元素作为信息内容的主要持有者。但是,允许使用属性来保存有关元素内容的元数据(例如,日期格式、度量单位或值集的标识)可以使实例文档更加简单和易于理解。

出生日期可能被表示为消息中的:

 <DateOfBirth>1975-06-03</DateOfBirth> 

然而,可能需要更多信息,例如如何验证出生日期。这可以被定义为一个属性,使得消息中的元素看起来像:

<DateOfBirth VerifiedBy="View of Birth Certificate">1975-06-03</DateOfBirth> 
以下内容不合适:
<DateOfBirth VerifiedBy="View of Birth Certificate" ValueSet="ISO 8601" Code="2">1975-06-03</DateOfBirth>   

这里不清楚Code是在限定VerifiedBy还是ValueSet属性。更合适的表述应该是:

 <DateOfBirth>    
   <VerifiedBy Code="2">View of Birth Certificate</VerifiedBy>     
   <Value ValueSet="ISO 8601">1975-06-03</Value>
 </DateOfBirth>

该文档的URL似乎已经失效,但可以在此处找到存档:http://collections.europarchive.org/tna/20060924203316/http://govtalk.gov.uk/schemasstandards/developerguide_document.asp?docnum=946 - Nick Dowell

17

就我个人而言,我喜欢使用属性来表示简单的单值属性。元素更适合复杂类型或重复值。

对于单值属性,使用属性可以产生更紧凑的XML,并且在大多数API中更容易进行寻址。


5
难点在于“有机生长”的XML没有DTD或模式,无法确定什么是始终是单值属性。 - AnthonyWJones

7
作为一般规则,我完全避免使用属性。是的,属性更简洁,但元素更灵活,而灵活性是使用像XML这样的数据格式的最重要优势之一。今天是单个值,明天可能变成值列表。
此外,如果每个东西都是元素,您永远不必记住您如何对任何特定的信息进行建模。不使用属性意味着你少了一个需要考虑的事情。

5
为什么要踩这篇文章?这种做法除了臃肿外没有实质性的缺点,如果你担心这一点,那么你可能本来就不应该使用XML。在属性中所能做的事情,在元素中同样可以完成,但反过来则并非如此。 - Dan
2
我不是downvote,但这是我的观点。如果有人说“不要担心所有那些HTML块级标签,比如p``li``ol...只需使用div来代替。你可以用div做任何事情,而且永远不需要担心详细的语义。”即使属性不同,在这个例子中,效果是相似的。你失去了语义价值,在XML的情况下这很重要,即使它“工作”。 - J. M. Becker
4
如果属性和元素之间有清晰的语义意义,那么这会是一个很好的论点。事实上,这个问题一遍又一遍地被提出,恰恰是因为情况并非如此。 - Dan
请参考@AnthonyWJones上面的评论。我曾经多次将某些东西建模为属性,然后需要稍后将其转换为元素。最好完全避免这个问题。 - Dan

7

这主要是个人偏好问题。在我看来,使用元素进行分组,使用属性存储数据比起其他方式更加简洁。

例如,我更喜欢......

<?xml version="1.0" encoding="utf-8"?>
<data>
    <people>
        <person name="Rory" surname="Becker" age="30" />
        <person name="Travis" surname="Illig" age="32" />
        <person name="Scott" surname="Hanselman" age="34" />
    </people>
</data>

...与其...

<?xml version="1.0" encoding="utf-8"?>
<data>
    <people>
        <person>
            <name>Rory</name>
            <surname>Becker</surname>
            <age>30</age>
        </person>
        <person>
            <name>Travis</name>
            <surname>Illig</surname>
            <age>32</age>
        </person>
        <person>
            <name>Scott</name>
            <surname>Hanselman</surname>
            <age>34</age>
        </person>
    </people>
</data>

然而,如果我有一些不容易用20-30个字符表示或包含许多引号或其他需要转义的字符的数据,那么我会说是时候使用元素了... 可能需要使用CData块。

<?xml version="1.0" encoding="utf-8"?>
<data>
    <people>
        <person name="Rory" surname="Becker" age="30" >
            <comment>A programmer whose interested in all sorts of misc stuff. His Blog can be found at http://rorybecker.blogspot.com and he's on twitter as @RoryBecker</comment>
        </person>
        <person name="Travis" surname="Illig" age="32" >
            <comment>A cool guy for who has helped me out with all sorts of SVn information</comment>
        </person>
        <person name="Scott" surname="Hanselman" age="34" >
            <comment>Scott works for MS and has a great podcast available at http://www.hanselminutes.com </comment>
        </person>
    </people>
</data>

4
请看 Ned Batchelder 的 Elements vs. attributes
他很好地解释了元素和属性的优缺点,并提出以下建议:
推荐:对于将由业务应用程序生成或使用的数据,请使用元素,对于元数据,请使用属性。
重要提示:请参见下面 @maryisdead 的评论以获得进一步的澄清。

5
实际上他并不这样认为。这只是来自ASC X12 REference Model For XML Design的一句话,他实际上对此进行了分析。他的建议是:“我建议使用属性,除非你真正需要元素。如果一个东西可以重复,或者本身就有结构,或者其语义基于它在同级中的顺序,那么你需要使用元素。” - maryisdead
Ned更有代表性的话是:“其次,我设计了相关系统,我认为属性决策是正确的。它们都是简单数据类型,无序,并且只能出现一次。在这种情况下,属性是完全合理的,并且意味着您可以避免结束标记的开销。” - dbasnett

2

我的个人经验法则是:如果一个元素只能包含其中的一个内容,并且它是原子数据(如id、name、age、type等),那么应该使用属性,否则应该使用元素。


2
属性的限制告诉您可以和不能使用它们的位置:属性名称必须是唯一的,它们的顺序无关紧要,并且名称和值都只能包含文本内容。相比之下,元素可以具有非唯一名称、有重要的排序,以及可以具有混合内容。
在映射到遵循这些规则的数据结构的领域中,属性可用于对象上的属性名称和值,表格行中的列,字典中条目的名称和值。(但如果属性不都是值类型或字典中的条目不是字符串,则无法使用属性。)

1

这里有另一种可以帮助区分元素和属性的策略:考虑对象并记住MVC。

对象可以拥有成员(对象变量)和属性(具有setter和getter的成员)。属性在MVC设计中非常有用,允许进行更改通知机制。

如果采取这个方向,属性将用于内部应用程序数据,用户无法更改;经典示例将是ID或DATE_MODIFIED。因此,元素将用于用户可以修改的数据。

因此,以下内容对图书管理员首先添加图书项目(或杂志),然后可以编辑其名称作者ISBN等是有意义的:

<?xml version="1.0" encoding="utf-8"?>
<item id="69" type="book">
    <authors count="1">
        <author>
            <name>John Smith</name>
        <author>
    </authors>
    <ISBN>123456790</ISBN>
</item>

1
这根本没有任何意义 - 根据ASP.NET MVC的实现方式来设计您的基于XML的内容。 - John Saunders

1

我倾向于在数据需要被人类读者知道时使用元素,在只用于处理(例如ID)时使用属性。这意味着我很少使用属性,因为大部分数据与正在建模的领域相关。


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