在工作中,我们被要求创建XML文件以将数据传递到另一个离线应用程序,然后创建第二个XML文件以传回以更新我们的一些数据 . 在此过程中,我们一直在与其他应用程序的团队讨论XML文件的结构 .
我提出的样本基本上是这样的:
<INVENTORY>
<ITEM serialNumber="something" location="something" barcode="something">
<TYPE modelNumber="something" vendor="something"/>
</ITEM>
</INVENTORY>
另一个团队表示,这不是行业标准,属性应仅用于元数据 . 他们建议:
<INVENTORY>
<ITEM>
<SERIALNUMBER>something</SERIALNUMBER>
<LOCATION>something</LOCATION>
<BARCODE>something</BARCODE>
<TYPE>
<MODELNUMBER>something</MODELNUMBER>
<VENDOR>something</VENDOR>
</TYPE>
</ITEM>
</INVENTORY>
我建议第一个的原因是创建的文件的大小要小得多 . 传输过程中将有大约80000个项目在文件中 . 实际上他们的建议比我建议的大三倍 . 我搜索了所提到的神秘的“行业标准”,但我能找到的最接近的是XML属性应该只用于元数据,但是辩论的是关于什么是实际的元数据 .
经过长时间的解释(对不起),您如何确定什么是元数据,在设计XML文档的结构时,您应该如何决定何时使用属性或元素?
20 回答
我用这个经验法则:
属性是自包含的东西,即颜色,ID,名称 .
元素具有或可能具有自己的属性或包含其他元素 .
所以你的很近 . 我会做的事情如下:
EDIT :根据以下反馈更新了原始示例 .
属性的一些问题是:
属性不能包含多个值(子元素可以)
属性不易扩展(用于将来的更改)
属性无法描述结构(子元素可以)
属性更难以通过程序代码进行操作
属性值不容易针对DTD进行测试
如果使用属性作为数据容器,则最终会得到难以阅读和维护的文档 . 尝试使用元素来描述数据 . 仅使用属性提供与数据无关的信息 .
不要这样结束(这不是XML应该如何使用):
资料来源:http://www.w3schools.com/xml/xml_dtd_el_vs_attr.asp
"XML"代表“可扩展标记语言” . 标记语言意味着数据是文本,标记有关结构或格式的元数据 .
XHTML是按照预期方式使用的XML示例:
在这里,元素和属性之间的区别很明显 . 文本元素显示在浏览器中,属性是有关如何显示它们的说明(尽管有一些标签不能以这种方式工作) .
当XML不是用作标记语言而是用作数据序列化语言时会产生混淆,其中"data"和"metadata"之间的区别更加模糊 . 因此,元素和属性之间的选择或多或少是任意的,除了不能用属性表示的东西(参见feenster的答案) .
XML元素与XML属性
XML就是协议 . First defer to any existing XML schemas or established conventions within your community or industry.
如果您确实处于从头开始定义架构的情况,以下是一些应该通知 element vs attribute decision 的一般注意事项:
这可能取决于您的使用情况 . 用于表示从数据库生成的结构化数据的XML可以很好地与最终将字段值作为属性放置 .
但是,用作消息传输的XML通常使用更多元素会更好 .
例如,假设我们在答案中提出了这个XML: -
现在我们要将ITEM元素发送到设备以打印条形码,但是可以选择编码类型 . 我们如何表示所需的编码类型?突然间,我们有点姗姗来迟地意识到条形码不是单一的自动值,而是可以通过打印时所需的编码进行限定 .
关键在于,除非您构建某种XSD或DTD以及命名空间以将结构固定在一起,否则最好的选择就是打开您的选项 .
当IMO XML可以在不破坏使用它的现有代码的情况下进行弯曲时,它是最有用的 .
我在架构设计中使用以下关于属性与元素的指南:
为长时间运行的文本使用元素(通常是string或normalizedString类型的文本)
如果元素有两个值(例如eventStartDate和eventEndDate)的分组,则不要使用属性 . 在前面的示例中,"event"应该有一个新元素,它可能包含startDate和endDate属性 .
营业日期,日期时间和数字(例如计数,金额和费率)应该是要素 .
非商业时间元素,例如上次更新,过期应该是属性 .
哈希码和索引等非商业号码应该是属性 . *如果类型将使用元素复杂 .
如果值是简单类型且不重复,请使用属性 .
xml:id和xml:lang必须是引用XML模式的属性
在技术上可行时首选属性 .
属性的首选项是它提供以下内容:
唯一(该属性不能多次出现)
顺序没关系
以上属性是可继承的(这是"all"内容模型在当前模式语言中不支持的内容)
奖励是它们不那么冗长并且占用更少的带宽,但这并不是优先考虑属性而非元素的理由 .
我在技术上可行时添加,因为有时候无法使用属性 . 例如,属性集选择 . 例如,使用当前模式语言无法使用(startDate和endDate)xor(startTS和endTS)
如果XML Schema开始允许限制或扩展“所有”内容模型,那么我可能会放弃它
这个问题没有普遍的答案(我参与了W3C规范的创建) . XML可用于多种用途 - 类文本文档,数据和声明性代码是最常见的三种 . 我也经常使用它作为数据模型 . 这些应用程序的某些方面的属性更常见,而其他方面的子元素更自然 . 还有各种工具的功能,使其更容易或更难使用 .
XHTML是属性具有自然用途的一个领域(例如,在class ='foo'中) . 属性没有顺序,这可能使某些人更容易开发工具 . 没有架构,OTOH属性更难键入 . 我还发现命名空间属性(foo:bar =“zork”)在各种工具集中通常难以管理 . 但是看看一些W3C语言,看看常见的混合物 . SVG,XSLT,XSD,MathML是众所周知语言的一些例子,它们都具有丰富的属性和元素 . 有些语言甚至允许多于一种方式来做,例如
要么
请注意,这些在语法上并不等同,需要在处理工具中明确支持)
我的建议是查看离您的应用程序最近的区域的常规做法,并考虑您可能希望应用的工具集 .
最后确保将命名空间与属性区分开来 . 一些XML系统(例如Linq)将名称空间表示为API中的属性 . 国际海事组织这是丑陋的,可能令人困惑 .
如有疑问,KISS - 当您没有明确的理由使用属性时,为什么要混合属性和元素 . 如果您以后决定定义XSD,那么最终也会变得更干净 . 然后,如果您以后决定从XSD生成类结构,那么也会更简单 .
其他人已经介绍了如何从元素中区分属性,但是从更一般的角度来看,将所有内容放在属性中是因为它使得生成的XML更小是错误的 .
XML不是设计得紧凑,而是便携和人类可读 . 如果要减小传输中的数据大小,请使用其他内容(例如google's protocol buffers) .
百万美元的问题!
首先,现在不要太担心性能 . 你会惊讶于优化的xml解析器会快速翻阅你的xml . 更重要的是,您对未来的设计是什么:随着XML的发展,您将如何保持松散的耦合和互操作性?
更具体地说,您可以使元素的内容模型更复杂,但扩展属性更难 .
无论哪种方式都可以论证,但是你的同事是正确的,因为XML应该用于“标记”或围绕实际数据的元数据 . 就你而言,你是对的,因为在用XML建模你的域时,有时很难确定元数据和数据之间的界限 . 在实践中,我所做的是假装标记中的任何内容都被隐藏,并且只有标记外的数据是可读的 . 文件是否以这种方式有意义?
众所周知,XML非常笨重 . 对于运输和存储,如果您能够负担得起处理能力,强烈建议使用压缩 . 由于其重复性,XML压缩得很好,有时非常好 . 我有大文件压缩到原始大小的5%以下 .
支持你的立场的另一点是,虽然另一个团队正在争论风格(因为大多数XML工具将像所有#PCDATA文档一样轻松地处理全属性文档),你正在争论实用性 . 虽然风格不能完全忽略,但技术优点应该更加重要 .
这在很大程度上取决于偏好 . 我尽可能使用Elements进行数据分组和数据属性,因为我认为这比替代方案更紧凑 .
比如我更喜欢......
...代替....
但是,如果我的数据不容易表示比方说20-30个字符或包含许多引号或其他需要转义的字符然后我会说它是时候打破元素...可能与CData块 .
将元素用于元数据的数据和属性(有关元素数据的数据) .
如果元素在选择字符串中显示为谓词,则表明它应该是一个属性 . 同样,如果一个属性永远不会被用作谓词,那么它可能不是有用的元数据 .
请记住,XML应该是机器可读的而不是人类可读的,对于大型文档,XML压缩得非常好 .
如何利用我们辛苦赚取的面向对象直觉?我通常发现很容易认为哪个是对象,哪个是对象的属性或者它指的是哪个对象 .
任何直观有意义的对象都应该作为元素 . 它的属性(或属性)将是xml中具有属性的子元素中的这些元素的属性 .
我认为对于更简单的情况,例如在示例中,对象取向类比工作可以确定哪个是元素,哪个是元素的属性 .
这两种存储对象属性的方法都是完全有效的 . 你应该背离务实的考虑 . 尝试回答以下问题:
哪种表示导致更快的数据解析\生成?
哪种表示可以加快数据传输速度?
可读性是否重要?
...
对一些不良信息进行了几处修正:
@John Ballinger:Attributies可以包含任何字符数据 . <>&“'需要分别转义为&lt;&gt;&amp;&quot;和' . 如果您使用XML库,它将为您处理 .
地狱,一个属性可以包含二进制数据,如图像,如果你真的想要,只需通过base64编码并使其成为数据:URL .
@feenster:在IDS或NAMES的情况下,属性可以包含以空格分隔的多个项目,其中包括数字 . Nitpicky,但这最终可以节省空间 .
使用属性可以使XML与JSON保持竞争力 . 见Fat Markup: Trimming the Fat Markup Myth one calorie at a time .
这在HTML中非常清楚,可以清楚地看到属性和标记的差异:
所有数据都在标记之间
属性用于表征此数据(例如格式)
如果你只是将纯数据作为XML,那么就会有一个不太明显的区别 . 数据可以位于标记之间或作为属性 .
=>大多数数据应该在标记之间 .
如果你想在这里使用属性:你可以将数据分为两类:数据和“元数据”,其中元数据不是你要呈现的记录的一部分,但是诸如“格式版本”,“创建日期”之类的东西等
也可以说:“使用属性来表征标签,使用标签自己提供数据 . ”
我总是对这些讨论的结果感到惊讶 . 对我来说,有一个非常简单的规则来决定数据是属于属性还是属于内容,这是数据是否具有可导航的子结构 .
因此,例如,非标记文本始终属于属性 . 总是 .
列表属于子结构或内容 . 随着时间的推移可能包含嵌入的结构化子内容的文本属于内容 . (根据我的经验,当使用XML进行数据存储或交换时,相对较少 - 带有标记的文本 . )
以这种方式编写的XML模式很简洁 .
每当我看到像
<car><make>Ford</make><color>Red</color></car>
这样的情况时,我认为自己"gee did the author think that there were going to be sub-elements within the make element?"<car make="Ford" color="Red" />
的可读性要高得多,毫无疑问如何处理空白等 .鉴于只有空格处理规则,我相信这是XML设计者的明确意图 .
我同意feenster . 如果可以,请远离属性 . 元素是进化友好的,并且在Web服务工具包之间更具互操作性 . 您永远不会发现这些工具包使用属性序列化您的请求/响应消息 . 这也很有意义,因为我们的消息是Web服务工具包的数据(而不是元数据) .
随着时间的推移,属性很容易变得难以管理 . 我个人总是远离他们 . 解析器和用户都更加明确,可读/可用元素 .
只有我曾经使用它们的时间是定义资产网址的文件扩展名:
我想如果你知道100%属性不需要扩展你可以使用它们,但你知道多少次 .