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文档的结构时,应该如何决定何时使用属性或元素?
我使用这个经验法则:
- 一个属性是一个独立的东西,即一个颜色,一个ID,一个名字。
- 一个元素是或者可以拥有自己的属性或者包含其他元素的东西。
所以你的接近。 我会做这样的事情:
编辑 :根据下面的反馈更新了原始示例。
<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中的这些元素的属性或具有属性的子元素的属性。
我认为对于比较简单的情况,比如在示例中,对象方向类推可以找出哪个是元素,哪个是元素的属性。
这两种存储对象属性的方法都是完全有效的。 你应该偏离实际的考虑。 尝试回答以下问题:
- 哪种表示导致更快的数据parsing\生成?
- 哪种表示导致更快的数据传输?
-
可读性是否重要?
…
这主要是一个偏好问题。 我使用元素进行分组和属性的数据在可能的情况下,因为我认为这是比替代更紧凑。
比如我比较喜欢…..
<?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中非常清晰,可以清楚地看到属性和标记的差异:
- 所有数据都在标记之间
- 属性用于表征这些数据(例如格式)
如果你只是将纯数据作为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脂肪标记神话一卡路里 。
- 打印org.w3c.dom.Document到stdout的最简单方法是什么?
- 在XDocument中查找元素?
- 如果我在XML布局中声明一个片段,我该如何将它传递给一个Bundle?
- InflateException:二进制XML文件行#1:由于OutOfMemoryError引起的类错误
- 如何评论XML标签内的属性?
- 任何从XML实例文档生成XSD模式的工具?
- 由DataContractSerializer创build的XML的格式
- XML序列化和inheritancetypes
- 从javax.xml.transform.Transformer的漂亮打印输出只有标准的Java API(缩进和Doctype定位)