我应该使用XML中的元素还是属性?

我正在学习W3School的XML属性 。

作者提到以下(重点是我的):

XML元素与属性

<person sex="female"> <firstname>Anna</firstname> <lastname>Smith</lastname> </person> 

 <person> <sex>female</sex> <firstname>Anna</firstname> <lastname>Smith</lastname> </person> 

在第一个例子中,性是一个属性。 最后,性是一个元素。 两个例子都提供了相同的信息。

没有关于何时使用属性以及何时使用元素的规则。 属性在HTML中很方便。 在XML中,我的build议是避免它们。 改用元素。

避免XML属性?

使用属性的一些问题是:

  • 属性不能包含多个值(元素可以)
  • 属性不能包含树结构(元素可以)
  • 属性不容易扩展(为了将来的变化)

属性很难阅读和维护。 使用数据元素。 使用属性来获取与数据无关的信息。

所以作者的观点是一个着名的,或者这是XML的最佳做法?

XML中的属性应该避免吗?

W3Schools还提到了以下内容(重点是我的):

元数据的XML属性

有时ID引用被分配给元素。 这些ID可以用来识别XML元素,就像HTML中的ID属性一样。 这个例子演示了这个:

 <messages> <note id="501"> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> <note id="502"> <to>Jani</to> <from>Tove</from> <heading>Re: Reminder</heading> <body>I will not</body> </note> </messages> 

上面的ID只是一个标识符,用于标识不同的注释。 这不是笔记本身的一部分。

我在这里想说的是元数据(关于数据的数据)应该作为属性存储,而数据本身应该作为元素存储。

属性或元素的使用通常由您尝试build模的数据决定。

例如,如果某个实体是数据的一部分,那么build议将其作为一个元素。 例如,员工的姓名是员工数据的重要组成部分。

现在,如果您想要传达METADATA有关数据(提供有关数据的其他信息的东西),但实际上并不是数据的一部分,则最好将其作为属性。 例如,假设每个员工都有一个后端处理所需的GUID,那么使其成为一个属性就更好了(GUID并不是传达真正有用的信息给查看XML的人,但可能是其他用途所必需的)

没有什么规则可以说某事应该是属性或元素。

它不需要不惜一切代价避免属性。有时它们比元素更容易build模。 这真的取决于你想要expression的数据。

尤其重要的是,将属性放在属性中可以减less冗长的XML。

比较

 <person name="John" age="23" sex="m"/> 

反对

 <person> <name> John </name> <age> <years> 23 </years> </age> <sex> m </sex> </person> 

是的,这是有点偏见和夸大,但你明白了

我的0.02五年后的OP是完全相反的。 让我解释。

  1. 分组类似数据时使用元素,以及该数据的属性。
  2. 不要使用元素的一切。
  3. 如果数据重复(1到多),这可能是一个元素
  4. 如果数据从不重复,只有在与其他事物相关时才有意义,这是一个属性。
  5. 如果数据没有其他属性(即名称),那么这是一个属性
  6. 像组件一样支持集合parsing(ie / xml / character)
  7. 重复使用相似的元素名称来支持parsing数据
  8. 永远不要使用元素名称中的数字来显示位置。 (即字符1,字符2)这种做法很难parsing(见#6,parsing代码必须/字符1,/字符2等不是简单/字符。

考虑另一种方式:

  • 首先将所有数据视为一个属性。
  • 从逻辑上将属性分组为元素。 如果你知道你的数据,你很less需要将属性转换为元素。 您可能已经知道什么时候元素(集合或重复的数据)是必要的
  • 在逻辑上将元素分组在一起
  • 当你遇到这种情况,你需要扩展,添加新的元素/属性基于上述过程的逻辑结构。 添加一个新的子元素集合不会“破坏”你的devise,并且随着时间的推移会更容易阅读。

例如,看一个简单的书籍和主要人物集合,标题将永远不会有“孩子”,这是一个简单的元素。 每个angular色都有一个名字和年龄。

  <book title='Hitchhiker&apos;s Guide to the Galaxy' author='Douglas Adams'> <character name='Zaphod Beeblebrox' age='100'/> <character name='Arthur Dent' age='42'/> <character name='Ford Prefect' age='182'/> </book> <book title='On the Road' author='Jack Kerouac'> <character name='Dean Moriarty' age='30'/> <character name='Old Bull Lee' age='42'/> <character name='Sal Paradise' age='42'/> </book> 

你可能会争辩说,一本书可能有多个作者。 好吧,只需添加新的作者元素即可展开(可以select删除原来的@author)。 当然,你已经打破了原来的结构,但在实践中,这是非常罕见的,而且很容易解决。 任何假定单个作者的原始XML的消费者将不得不改变(他们可能会改变他们的数据库以将作者从“书”表中的列移动到“作者”表)。

 <book title='Hitchhiker&apos;s Guide to the Galaxy'> <author name='Douglas Adams'/> <author name='Some Other Guy'/> <character name='Zaphod Beeblebrox' age='100'/> <character name='Arthur Dent' age='42'> <character name='Ford Prefect' age='182'/> </book> 

我用Googlesearch确切的问题。 首先我登陆这篇文章, http://www.ibm.com/developerworks/library/x-eleatt/index.html 。 虽然这样一个简单的问题,感觉太长了。 无论如何,我已经读过关于这个话题的所有答案,没有find一个令人满意的总结。 因此,我回到了后面的文章。 这里是一个总结:

什么时候使用元素,什么时候使用属性来显示信息位?

  • 如果有问题的信息可以自己用元素标记出来,把它放在一个元素中。
  • 如果信息适合于属性表单,但是可能会在同一个元素上以同一名称的多个属性结束,请使用子元素。
  • 如果信息需要处于类似标准DTD的属性types(如ID,IDREF或ENTITY)中,请使用属性。
  • 如果信息不应该被标准化为空格,请使用元素。 ( XML处理器以可以更改属性值的原始文本的方式规范化属性 。)

核心内容的原则

如果您认为所涉及的信息是以XML表示或传达的基本材料的一部分,则将其放入元素中。 如果您认为这些信息是主要通信的外围或附带信息,或纯粹旨在帮助应用程序处理主要通信,请使用属性。

结构化信息原理

如果信息以结构化的formsexpression,特别是如果结构可以是可扩展的,则使用元素。 如果信息表示为primefaces标记,则使用属性。

可读性原则

如果信息旨在被人阅读和理解,请使用元素。 如果信息最容易被机器理解和消化,请使用属性。

元素/属性绑定的原则

如果您需要通过其他属性修改其值,请使用元素。 […]有一个属性修改另一个属性几乎总是一个可怕的主意。

这是文章重要部分的简短摘要。 如果您希望查看每个案例的示例和完整说明,请参阅原文。

属性模型映射。 元素上的一组属性直接定义到名称/值映射中,其中的值是文本或任何可序列化的值types。 例如,在C#中,任何Dictionary<string, string>对象都可以表示为XML属性列表,反之亦然。

元素强调的不是这种情况。 虽然总是可以将名称/值映射转换为一组元素,但事实并非如此,例如:

 <map> <key1>value</key1> <key1>another value</key1> <key2>a third value</key2> </map> 

如果将其转换为地图,则会失去两件事:与key1关联的多个值,以及key1出现在key2之前的事实。

如果您查看用于以这种格式更新信息的DOM代码,这一点的意义变得更加清晰。 例如,写这个很简单:

 foreach (string key in map.Keys) { mapElement.SetAttribute(key, map[key]); } 

该代码简洁明了。 对比一下,说:

 foreach (string key in map.Keys) { keyElement = mapElement.SelectSingleNode(key); if (keyElement == null) { keyElement = mapElement.OwnerDocument.CreateElement(key); mapElement.AppendChild(keyElement); } keyElement.InnerText = value; } 

这一切都取决于用于什么XML。 当它主要是在软件和机器之间进行互操作的时候,比如Web服务,如果仅仅为了一致性(而且一些框架更喜欢这种方式,例如WCF),则更容易去全部元素。 如果它是针对人类消费的 – 即主要由人们创build和/或读取 – 则明智地使用属性可以提高可读性; XHTML是一个合理的例子,也是XSLT和XML Schema。

我通常在属性是元数据的基础上工作 – 即关于数据的数据。 我做的一件事是避免将列表放在属性中。 例如

 attribute="1 2 3 7 20" 

否则,你有一个额外的parsing级别来提取每个元素。 如果XML提供了列表的结构和工具,那么为什么要强加另一个自己。

一种情况下,您可能想要优先编码属性是通过SAXparsing器处理速度。 使用SAXparsing器,您将获得包含元素名称和属性列表的元素callback。 如果你使用了多个元素,那么你会得到多个callback(每个元素一个)。 这是一个多less的负担/时间,当然是辩论,但也许值得考虑。

你不能把一个CDATA放在一个属性中。 根据我的经验,迟早你会想把单引号,双引号和/或整个XML文档放到一个“成员”中,如果这是一个属性,你会诅咒使用属性的人的元素。

注:我在XML方面的经验主要涉及清理其他人的。 这些人似乎遵循了“XML就像暴力,如果使用它没有解决你的问题,那么你没有足够的使用”这句古老的谚语。

这是属性是关于数据的数据的一个例子。

数据库通过其ID属性进行命名。

数据库的“type”属性表示在数据库标签内部预期会发现什么。

  <databases> <database id='human_resources' type='mysql'> <host>localhost</host> <user>usrhr</user> <pass>jobby</pass> <name>consol_hr</name> </database> <database id='products' type='my_bespoke'> <filename>/home/anthony/products.adb</filename> </database> </databases> 

作者的观点是正确的(除了属性可能包含一个值列表)。 问题是你是否在意他的观点。

随你便。

这是因为那种垃圾,你应该避免学校。 如果有的话,这比他们对JavaScript的可怕的东西更糟糕。

作为一般规则,我build议内容 – 即最终用户预期要消费的数据(不pipe是人类阅读还是机器接收处理信息) – 最好包含在一个元素中。 元数据 – 例如与一段内容相关联的ID,但仅用于内部使用,而不是显示给最终用户 – 应该属于一个属性。

在决定XML格式时,需要记住的另一件事情是:如果我记得正确,“id”属性的值不能全部为数字,它们必须符合XML中名称的规则。 当然,这些价值观必须是独一无二的。 我有一个项目必须处理不符合这些要求的文件(尽pipe它们在其他方面都是干净的XML),这使得处理文件变得更加复杂。

你可以用语义的方式来看问题。

如果数据更紧密的链接元素,这将是一个属性。

即:一个元素的ID,我会把它作为元素的属性。

但是,parsing文档属性的确会比元素更令人头痛。

一切取决于你,以及你如何devise你的模式。