我应该使用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到多),这可能是一个元素
- 如果数据从不重复,只有在与其他事物相关时才有意义,这是一个属性。
- 如果数据没有其他属性(即名称),那么这是一个属性
- 像组件一样支持集合parsing(ie / xml / character)
- 重复使用相似的元素名称来支持parsing数据
- 永远不要使用元素名称中的数字来显示位置。 (即字符1,字符2)这种做法很难parsing(见#6,parsing代码必须/字符1,/字符2等不是简单/字符。
考虑另一种方式:
- 首先将所有数据视为一个属性。
- 从逻辑上将属性分组为元素。 如果你知道你的数据,你很less需要将属性转换为元素。 您可能已经知道什么时候元素(集合或重复的数据)是必要的
- 在逻辑上将元素分组在一起
- 当你遇到这种情况,你需要扩展,添加新的元素/属性基于上述过程的逻辑结构。 添加一个新的子元素集合不会“破坏”你的devise,并且随着时间的推移会更容易阅读。
例如,看一个简单的书籍和主要人物集合,标题将永远不会有“孩子”,这是一个简单的元素。 每个angular色都有一个名字和年龄。
<book title='Hitchhiker'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'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你的模式。