XML属性与XML元素

在工作中,我们被要求创buildXML文件,将数据传递给另一个离线应用程序,然后创build第二个XML文件传回来更新我们的一些数据。 在这个过程中,我们一直在与其他应用程序的团队讨论XML文件的结构。

我提出的样本基本上是这样的:

<INVENTORY> <ITEM serialNumber="something" location="something" barcode="something"> <TYPE modelNumber="something" vendor="something"/> </ITEM> </INVENTORY> 

另一个团队说,这不是行业标准,属性只能用于元数据。 他们build议:

 <INVENTORY> <ITEM> <SERIALNUMBER>something</SERIALNUMBER> <LOCATION>something</LOCATION> <BARCODE>something</BARCODE> <TYPE> <MODELNUMBER>something</MODELNUMBER> <VENDOR>something</VENDOR> </TYPE> </ITEM> </INVENTORY> 

我build议的第一个原因是创build的文件的大小要小得多。 传输过程中将会有大约80000个文件。 现实中的build议是我build议的三倍。 我search了所提到的神秘的“行业标准”,但我能find的最接近的是XML属性只能用于元数据,但是辩论是关于什么是元数据。

在冗长的解释之后(对不起)你如何确定什么是元数据,在deviseXML文档的结构时,应该如何决定何时使用属性或元素?

我使用这个经验法则:

  1. 一个属性是一个独立的东西,即一个颜色,一个ID,一个名字。
  2. 一个元素是或者可以拥有自己的属性或者包含其他元素的东西。

所以你的接近。 我会做这样的事情:

编辑 :根据下面的反馈更新了原始示例。

  <ITEM serialNumber="something"> <BARCODE encoding="Code39">something</BARCODE> <LOCATION>XYX</LOCATION> <TYPE modelNumber="something"> <VENDOR>YYZ</VENDOR> </TYPE> </ITEM> 

一些属性的问题是:

  • 属性不能包含多个值(子元素可以)
  • 属性不容易扩展(为了将来的变化)
  • 属性不能描述结构(子元素可以)
  • 属性更难以被程序代码操纵
  • 属性值不容易testingDTD

如果您使用属性作为数据容器,则最终会生成难以读取和维护的文档。 尝试使用元素来描述数据。 仅使用属性来提供与数据无关的信息。

不要这样结束(这不是应该如何使用XML):

 <note day="12" month="11" year="2002" to="Tove" from="Jani" heading="Reminder" body="Don't forget me this weekend!"> </note> 

资料来源: http : //www.w3schools.com/xml/xml_dtd_el_vs_attr.asp

“XML”代表“可扩展标记语言”。 标记语言意味着数据是文本,用关于结构或格式的元数据标记

XHTML是一个XML使用的方式:

 <p><span lang="es">El Jefe</span> insists that you <em class="urgent">MUST</em> complete your project by Friday.</p> 

在这里,要素和属性之间的区别是明确的。 文本元素显示在浏览器中,属性是关于如何显示它们的说明(虽然有几个标签不能这样工作)。

当XML不是用作标记语言,而是用作数据序列化语言时,会出现混淆,“数据”和“元数据”之间的区别更为模糊。 所以元素和属性之间的select或多或less是任意的,除了不能用属性表示的东西(参见feenster的答案)。

XML元素与XML属性

XML是关于协议的。 首先请遵循您的社区或行业中现有的XML模式或已build立的约定。

如果您确实处于从头开始定义您的模式的情况下,下面是一些通用的考虑因素,应该通知元素与属性的决定

 <versus> <element attribute="Meta content"> Content </element> <element attribute="Flat"> <parent> <child>Hierarchical</child> </parent> </element> <element attribute="Unordered"> <ol> <li>Has</li> <li>order</li> </ol> </element> <element attribute="Must copy to reuse"> Can reference to re-use </element> <element attribute="For software"> For humans </element> <element attribute="Extreme use leads to micro-parsing"> Extreme use leads to document bloat </element> <element attribute="Unique names"> Unique or non-unique names </element> <element attribute="SAX parse: read first"> SAX parse: read later </element> <element attribute="DTD: default value"> DTD: no default value </element> </versus> 

这可能取决于您的使用情况。 用于表示从数据库生成的结构化数据的XML可能最适合将最终字段值作为属性放置。

但是,用作消息传输的XML往往会使用更多的元素。

例如,假设我们在回答中提出了这个XML:

 <INVENTORY> <ITEM serialNumber="something" barcode="something"> <Location>XYX</LOCATION> <TYPE modelNumber="something"> <VENDOR>YYZ</VENDOR> </TYPE> </ITEM> </INVENTORY> 

现在我们想把ITEM元素发送到设备来打印他的条形码,但是有一个编码types的select。 我们如何表示所需的编码types? 突然之间,我们有些后悔地意识到,条形码不是一个单一的自动值,而是可以用打印时所需的编码来限定。

  <ITEM serialNumber="something"> <barcode encoding="Code39">something</barcode> <Location>XYX</LOCATION> <TYPE modelNumber="something"> <VENDOR>YYZ</VENDOR> </TYPE> </ITEM> 

重点是除非你build立某种XSD或DTD以及命名空间来修复这个结构,否则最好的办法是让你的选项打开。

IMO XML是最有用的,当它可以折叠而不破坏现有的代码使用它。

在我的模式devise中,关于属性与元素,我使用了以下指导原则:

  • 对长时间运行的文本使用元素(通常是string或标准化stringtypes的元素)
  • 如果元素的两个值(例如,eventStartDate和eventEndDate)分组,则不要使用属性。 在前面的例子中,应该有一个“事件”的新元素,它可能包含startDate和endDate属性。
  • 商业date,date时间和数字(例如计数,数量和比率)应该是元素。
  • 非业务时间元素,如上次更新,到期应该是属性。
  • 非商业数字如哈希码和索引应该是属性。*如果types复杂,则使用元素。
  • 如果值是简单types,则不使用属性,不重复。
  • xml:id和xml:lang必须是引用XML模式的属性
  • 在技​​术上可能的情况下,首选属性。

属性的偏好是它提供了以下内容:

  • 唯一的(该属性不能多次出现)
  • 顺序无关紧要
  • 上述属性是可inheritance的(这是“所有”内容模型在当前模式语言中不支持的东西)
  • 奖励是他们不那么冗长,用尽较less的带宽,但这不是一个真正的理由偏好元素的属性。

在技​​术上可能的时候添加了因为有些时候使用属性是不可能的。 例如,属性集select。 例如,使用(startDate和endDate)xor(startTS和endTS)对于当前的模式语言是不可能的

如果XML模式开始允许“全部”内容模型被限制或扩展,那么我可能会放弃它

如果有疑问, KISS – 为什么混合属性和元素,当你没有明确的理由使用属性。 如果您稍后决定定义一个XSD,那么最终也将变得更清晰。 那么如果你以后决定从你的XSD中产生一个类结构的话,那也是很简单的。

这个问题没有普遍的答案(我大量参与了W3C规范的创build)。 XML可用于多种目的 – 文本类文档,数据和声明性代码是最常见的三种。 我也将其用作数据模型。 这些应用程序的属性更常见,而其他子元素更自然。 还有各种工具的特点,使它们更容易或更难使用它们。

XHTML是属性自然使用的一个领域(例如在class ='foo'中)。 属性没有顺序,这可能使一些人更容易开发工具。 OTOH属性很难在没有模式的情况下input。 我还发现命名空间属性(foo:bar =“zork”)在各种工具集中经常难以pipe理。 但是看看一些W3C语言来看看这个共同点。 SVG,XSLT,XSD,MathML是众所周知的语言的一些例子,并且都具有丰富的属性和元素。 有些语言甚至允许使用多种方式来完成,例如

 <foo title="bar"/>; 

要么

 <foo> <title>bar</title>; </foo>; 

请注意,这些在语法上不相同,需要在处理工具中明确支持)

我的build议是在最接近您的应用的地方查看惯例,并考虑您可能希望应用的工具集。

最后确保你区分名称空间和属性。 一些XML系统(如Linq)将名称空间表示为API中的属性。 海事组织这是丑陋的,可能会令人困惑。

百万美元的问题!

首先,现在不要太担心表演。 你会惊讶于一个优化的XMLparsing器将迅速通过你的XML。 更重要的是,你对未来的devise是什么:随着XML的发展,你将如何保持松耦合和互操作性?

更具体地说,可以使元素的内容模型更加复杂,但扩展属性更困难。

无论哪种方式都是有争议的,但是您的同事是正确的,即XML应该用于实际数据的“标记”或元数据。 对于你而言,你是对的,因为有时候很难确定元数据和数据之间的界限是用XMLbuild模你的域的时候。 实际上,我所做的是假装标记中的任何内容都是隐藏的,只有标记之外的数据才是可读的。 文件是否有这样的意义?

XML是非常庞大的。 对于运输和存储,如果您负担得起处理能力,强烈build议进行压缩。 由于XML的重复性,XML压缩得很好,有时非常好。 我已经有大文件压缩到不到原始大小的5%。

另一个支持你的立场的观点是,虽然另一个团队正在争论风格(因为大多数XML工具将处理一个全属性文档就像一个全部的PCDATA文档一样容易),你认为是实用性。 虽然风格不能完全忽略,但技术上的优点应该更加重视。

为元数据使用数据和属性元素(有关元素数据的数据)。

如果一个元素在selectstring中显示为一个谓词,那么就有一个很好的表示,它应该是一个属性。 同样,如果一个属性永远不会被用作谓词,那么也许它不是有用的元数据。

请记住,XML应该是机器可读的,而不是人类可读的,对于大型文档,XML压缩得非常好。

其他人已经介绍了如何区分元素的属性,但是从更一般的angular度来看,把所有的东西放在属性中,因为它使得生成的XML更小是错误的。

XML的devise不是紧凑的,而是便于携带和可读的。 如果你想减less传输中的数据的大小,然后使用其他的东西(如谷歌的协议缓冲区 )。

如何利用我们辛苦赚取的对象定向直觉? 我通常会发现,认为哪一个是一个对象,哪一个是对象的属性或者它指的是哪个对象是直接的。

无论哪一种直观的理解,物体都应该适合作为元素。 它的属性(或属性)将是xml中的这些元素的属性或具有属性的子元素的属性。

我认为对于比较简单的情况,比如在示例中,对象方向类推可以找出哪个是元素,哪个是元素的属性。

这两种存储对象属性的方法都是完全有效的。 你应该偏离实际的考虑。 尝试回答以下问题:

  1. 哪种表示导致更快的数据parsing\生成?
  2. 哪种表示导致更快的数据传输?
  3. 可读性是否重要?

这主要是一个偏好问题。 我使用元素进行分组和属性的数据在可能的情况下,因为我认为这是比替代更紧凑。

比如我比较喜欢…..

 <?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> 

HTML中非常清晰,可以清楚地看到属性和标记的差异:

  1. 所有数据都在标记之间
  2. 属性用于表征这些数据(例如格式)

如果你只是将纯数据作为XML,那么就不太清晰了。 数据可以介于标记或属性之间。

=>大多数数据应该位于标记之间。

如果你想在这里使用属性:你可以将数据分成两类:数据和“元数据”,其中元数据不是logging的一部分,你想呈现,但像“格式版本”,“创builddate”等等

 <customer format=""> <name></name> ... </customer> 

也可以说:“使用属性来表征标签,使用标签来提供数据本身”。

这些讨论的结果我总是感到惊讶。 对于我来说,判断数据是属于某个属性还是内容,还是数据是否具有可导航的子结构,都有一个非常简单的规则。

例如,非标记文本总是属于属性。 总是。

列表属于子结构或内容。 随着时间的推移文本可能包括embedded的结构化子内容属于内容。 (根据我的经验,使用XML进行数据存储或交换时,相对较less的是带有标记的文本。)

用这种方式编写的XML模式是简洁的。

每当我看到<car><make>Ford</make><color>Red</color></car> ,我想我自己“作者认为gee中将会有子元素做元素?“ <car make="Ford" color="Red" />明显更具可读性,毫无疑问,如何处理空白等等。

只要给出空白处理规则,我相信这是XMLdevise者的明确意图。

我同意feenster。 如果可以的话,远离属性。 元素是演变友好的和更多的Web服务工具包之间的互操作性。 你永远不会发现这些工具包使用属性序列化请求/响应消息。 这也是有道理的,因为我们的消息是一个Web服务工具包的数据(而不是元数据)。

随着时间的推移,属性很容易变得难以相信我。 我总是远离他们。 元素分析器和用户都更加明确和可读/可用。

只有我曾经使用它们的时间是定义资产url的文件扩展名:

 <image type="gif">wank.jpg</image> ...etc etc 

我想如果你知道100%的属性将不需要扩大你可以使用它们,但你知道多less次。

 <image> <url>wank.jpg</url> <fileType>gif</fileType> </image> 

只是几个更正一些不好的信息:

@John Ballinger:Attributies可以包含任何字符数据。 如果你使用一个XML库,它将会为你处理这个问题。

地狱,一个属性可以包含二进制数据,如图像,如果你真的想要,只需通过base64编码,并使其数据:URL。

@feenster:在IDS或NAMES(包含数字)的情况下,属性可以包含空格分隔的多个项目。 Nitpicky,但这可以最终节省空间。

使用属性可以保持XML与JSON的竞争力。 见脂肪标记:一次减less脂肪标记神话一卡路里