最佳实践:XML属性 vs XML元素 - 何时应使用元素,何时应使用属性?

25
这个XML数据的正确格式是哪一个,它们是否等效或者两者之间有权衡取舍?
1.
<sitemap>
  <category name="Animals">
    <section title="Dogs">
      <page url="/pics/greatdane.jpg" title="Great Dane"/>
    </section>
  </category>
</sitemap>

2.

<sitemap>
  <page>
    <category>Animals</category>
    <section>Dogs</section>
    <title>Great Dane</title>
    <url>/pics/greatdane.jpg</url>    
  </page>
</sitemap>

我已经使用我的样式表实现了第一个例子,看起来很好,但我不确定正确的格式应该是什么。


1
这是一个好问题,但标题不太好。 - Justin R.
是的,非常好的问题,但请更改标题。 - Daniel Rikowski
10个回答

21

属性(attributes)和元素(elements)的问题已经存在了十多年,没有正确答案。相反,考虑它们的区别,然后您应该能够决定使用哪个:

  • 一个属性只能有一个实例,尽管使用DTD或XML Schema可以强制执行此要求,而元素则不然;
  • 属性是无序的,而元素不是;
  • 如果没有子元素,则属性会导致更简洁的语法。比较:

    <page name="Sitemap"/>

与以下内容进行比较:

<page>
  <name>Sitemap</name>
</page>

我知道我更喜欢哪个;

  • 现在不是很相关,因为DTD在XML Schema之上几乎没有使用(如果有的话),但我还是会加上它:DTD允许属性的默认值(隐含),但对于元素没有这样的机制; 以及
  • 作为元素,元素可以有自己的子元素和属性。 很明显,属性不能。

所以,根据您的示例,您最内层的<page>元素具有URL属性(尽管由于某种原因它是图像 - 可能是预览图标? 如果是,属性名称就是误导性的)。 网页只有一个URL(通常), 所以这将是一个很好的例子,可以将其作为属性。

另一方面,如果您想要列出页面上的图像,则可能会有多个,因此您需要使用元素。

但是,在最后,大多数时候并没有正确或错误的答案,这在很大程度上是一个风格问题。


你说“节点”,但你的意思是“元素”。处理指令、注释和文本也是节点。这是理解XML许多复杂性的重要区别,比如XPath node()函数。 - Robert Rossney
非常正确。已经更正。 - cletus
另外需要补充的一点是,如果使用XSL转换XML,则无法解码属性中的实体(https://dev59.com/TXVD5IYBdhLWcg3wKYP-)。 - null

12

这两个例子并不相同,因为它们形成了不同的层次结构。一个站点地图是像第一个例子那样的类别列表吗?还是像第二个例子那样的页面列表?

这个问题的答案与元素与属性的问题无关。

关于元素和属性的问题: 这是您的第二个示例转换为属性方法:

<sitemap>
 <page    
  category='Animals'
  section='Dogs'
  title='Great Dane'
  url='/pics/greatdane.jpg'
  /> 
</sitemap>
上面的代码和您提到的第二种情况是相等的。选择其中一个的考虑因素之一是基于您是否将来可能修改架构。像以下示例中在url元素添加属性可能会是向后兼容的更改。在属性方法中,无法进行语义上相同的修改,因为您无法将属性附加到属性。
<sitemap>
 <page>    
  <category>Animals</category>
  <section>Dogs</section>    
  <title>Great Dane</title>    
  <url nofollow="true">/pics/greatdane.jpg</url>
 </page> 
</sitemap>

3

XML是一种可怕的文件格式,容易引起宗教战争。在你可以证明的情况下,做出你认为最好的选择。然而,你提供的两个例子有很大的不同:

第一种情况中,网站地图封装了一个分类,该分类又封装了一个部分,该部分又封装了一个页面。

在第二种情况中,网站地图封装了一个页面,该页面包含三个项目:类别、部分、标题和URL。这三个项目都没有包含其他项目,它们是兄弟节点,通常都在页面中。

由于这两种结构不同,所以取决于你的意图。

另一个问题是属性与一级标签的首选项。但正如我所说,那是一个不同的问题!


3

我认为当你考虑要添加更多狗时,答案就很明显了:

<sitemap>
  <category name="Animals">
    <section title="Dogs">
      <page url="/pics/greatdane.jpg" title="Great Dane"/>
      <page url="/pics/wienerdog.jpg" title="Wiener Dog"/>
    </section>
  </category>
</sitemap>

或者

<sitemap>
  <page>
    <category>Animals</category>
    <section>Dogs</section>
    <title>Great Dane</title>
    <url>/pics/greatdane.jpg</url>    
  </page>
  <page>
    <category>Animals</category>
    <section>Dogs</section>
    <title>Wiener Dog</title>
    <url>/pics/wienerdog.jpg</url>
  </page>
</sitemap>

2

这种情况通常没有对错之分,很大程度上取决于你需要如何访问数据。

第一种方法的一个好处是它可以轻松地支持一个部分中的多个页面和一个类别中的多个部分,而在第二种方法中,这些信息分散在不同的页面上。


2

我使用元素来存储数据,使用属性来存储元数据


1
我更喜欢第二种方式。元素应该用于描述数据(这是大多数情况下你在做的事情)。属性用于不与数据相关的值,例如元素的最大大小。

1
IBM发布了一篇名为XML设计原则的文章,提供了一些关于何时使用属性和元素的指导方针。我发现这篇文章很有用,但具体效果因人而异。

1
一个简单的经验法则:如果你可以将数据结构实现为名称/值对的无序映射,那么你可以使用元素的属性来表示它。如果不能(例如,如果你有多个名称,或者给定名称将有多个关联值,或者名称/值对的顺序很重要),那么具有属性的元素就是错误的表示。
还有两件事可能会使这种表示方式不正确:
  • 值包含标记。这可以在属性值中表示,但是这很麻烦,因为所有标记字符都必须转义为实体。而且,标记不会被解析。
  • 您正在使用XML模式验证,并且存在多个可允许的名称/值对集。XML模式只能为元素定义一组可允许的属性,而可以定义多个互斥的可允许子元素集。
使用属性的明显好处是它们会产生更简洁的XML。它们也比元素稍微快一点,解析速度更快。

1

第一种方法的扩展性更好。假设您需要添加动物部分的另一个属性,例如该部分的状态。我建议使用以下表示:

<sitemap>
  <category name="Animals">
    <section title="Dogs" status="draft">
      ...
    </section>
  </category>
</sitemap>

更好地传达以下事实:

  1. 名称是类别的属性
  2. 一个类别可以有多个部分
  3. 状态是部分的属性;并非类别中的所有部分都需要具有相同的状态。

简而言之,它使层次结构更清晰,并显示哪些属性适用于层次结构的每个级别。


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