在工作中,我们被要求创建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文档的结构时,您应该如何决定何时使用属性或元素?
答案 0 :(得分:135)
我使用这个经验法则:
所以你的很近。我会做的事情如下:
编辑:根据以下反馈更新了原始示例。
<ITEM serialNumber="something">
<BARCODE encoding="Code39">something</BARCODE>
<LOCATION>XYX</LOCATION>
<TYPE modelNumber="something">
<VENDOR>YYZ</VENDOR>
</TYPE>
</ITEM>
答案 1 :(得分:45)
属性的一些问题是:
如果使用属性作为数据容器,则最终会得到难以阅读和维护的文档。尝试使用元素来描述数据。仅使用属性提供与数据无关的信息。
不要这样结束(这不是应该如何使用XML):
<note day="12" month="11" year="2002"
to="Tove" to2="John" from="Jani" heading="Reminder"
body="Don't forget me this weekend!">
</note>
答案 2 :(得分:36)
“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不是用作标记语言而是用作数据序列化语言时会产生混淆,其中“数据”和“元数据”之间的区别更加模糊。因此,元素和属性之间的选择或多或少是任意的,除了不能用属性表示的东西(参见feenster的答案)。
答案 3 :(得分:30)
XML就是协议。 首先遵循社区或行业中任何现有的XML模式或既定惯例。
如果您确实处于从头开始定义架构的情况,以下是一些应该通知元素与属性决策的一般注意事项:
<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>
答案 4 :(得分:22)
这可能取决于您的使用情况。用于表示从数据库生成的结构化数据的XML可以很好地将最终字段值作为属性放置。
然而,使用更多元素的XML通常会更好地用作消息传输。
例如,假设我们在答案中提出了这个XML: -
<INVENTORY>
<ITEM serialNumber="something" barcode="something">
<Location>XYX</LOCATION>
<TYPE modelNumber="something">
<VENDOR>YYZ</VENDOR>
</TYPE>
</ITEM>
</INVENTORY>
现在我们要将ITEM元素发送到设备以打印条形码,但是可以选择编码类型。我们如何表示所需的编码类型?突然间,我们有点姗姗来迟地意识到条形码不是单一的自动值,而是可以通过打印时所需的编码进行限定。
<ITEM serialNumber="something">
<barcode encoding="Code39">something</barcode>
<Location>XYX</LOCATION>
<TYPE modelNumber="something">
<VENDOR>YYZ</VENDOR>
</TYPE>
</ITEM>
关键在于,除非您构建某种XSD或DTD以及命名空间以便将结构固定在一块石头上,否则最好让您的选项保持打开状态。
当IMO XML可以在不破坏使用它的现有代码的情况下进行弯曲时,它是最有用的。
答案 5 :(得分:9)
我在架构设计中使用以下关于属性与元素的指南:
属性的偏好是它提供以下内容:
我在技术上可行时添加 ,因为有时无法使用属性。例如,属性集选择。例如,使用当前模式语言无法使用(startDate和endDate)xor(startTS和endTS)
如果XML Schema开始允许限制或扩展“所有”内容模型,那么我可能会放弃它
答案 6 :(得分:8)
这个问题没有普遍的答案(我参与了W3C规范的创建)。 XML可用于多种用途 - 类文本文档,数据和声明性代码是最常见的三种。我也经常使用它作为数据模型。这些应用程序的某些方面属性更常见,而其他属性则更自然。还有各种工具的功能,使其更容易或更难使用。
XHTML是属性具有自然用途的一个领域(例如在class ='foo'中)。属性没有顺序,这可能使某些人更容易开发工具。没有架构,OTOH属性更难键入。我还发现命名空间属性(foo:bar =“zork”)通常难以在各种工具集中进行管理。但是看看一些W3C语言,看看常见的混合物。 SVG,XSLT,XSD,MathML是众所周知语言的一些例子,它们都具有丰富的属性和元素。有些语言甚至允许多于一种方式来做,例如
<foo title="bar"/>;
或
<foo>
<title>bar</title>;
</foo>;
请注意,这些语法在语法上并不相同,并且需要在处理工具中明确支持)
我的建议是查看离您的应用程序最近的区域的常规做法,并考虑您可能希望应用的工具集。
最后确保将命名空间与属性区分开来。一些XML系统(例如Linq)将名称空间表示为API中的属性。国际海事组织这是丑陋的,可能令人困惑。
答案 7 :(得分:7)
如果有疑问,KISS - 当您没有明确的理由使用属性时,为什么要混合属性和元素。如果您以后决定定义XSD,那么最终也会变得更干净。然后,如果您甚至后来决定从XSD生成类结构,那么也会更简单。
答案 8 :(得分:5)
首先,现在不要过于担心性能。你会惊讶于优化的xml解析器会快速浏览你的xml。更重要的是,您对未来的设计是什么:随着XML的发展,您将如何保持松耦合和互操作性?
更具体地说,您可以使元素的内容模型更复杂,但扩展属性更难。
答案 9 :(得分:5)
其他人已经介绍了如何从元素中区分属性,但是从更一般的角度来看,将所有内容放在属性中是因为它使得生成的XML更小是错误的。
XML不是设计得紧凑,而是可移植和人类可读。如果您想减少传输中的数据大小,请使用其他内容(例如google's protocol buffers)。
答案 10 :(得分:5)
使用元素数据和元数据元素(有关元素数据的数据)。
如果元素在选择字符串中显示为谓词,则表明它应该是一个属性。同样,如果一个属性永远不会被用作谓词,那么它可能不是有用的元数据。
请记住,XML应该是机器可读的而不是人类可读的,对于大型文档,XML压缩非常好。
答案 11 :(得分:4)
这在很大程度上取决于偏好。我尽可能使用Elements进行数据分组和数据属性,因为我认为这比替代方案更紧凑。
例如,我更喜欢......
<?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>
答案 12 :(得分:4)
无论哪种方式都可以论证,但是你的同事是正确的,因为XML应该用于“标记”或围绕实际数据的元数据。对于您而言,您是正确的,因为在使用XML建模您的域时,有时很难确定元数据和数据之间的界限。在实践中,我所做的是假装标记中的任何内容都被隐藏,并且只有标记外的数据是可读的。该文件是否有某种意义?
XML非常笨重。对于运输和存储,如果您能够负担得起处理能力,强烈建议使用压缩。由于其重复性,XML压缩得很好,有时非常好。我的大文件压缩到原始大小的5%以下。
支持你的立场的另一点是,虽然另一个团队正在争论风格(因为大多数XML工具将像所有#PCDATA文档一样轻松地处理全属性文档),你正在争论实用性。虽然风格不能完全忽略,但技术优点应该更加重要。
答案 13 :(得分:4)
如何充分利用我们辛苦挣来的面向对象的直觉?我通常发现很容易认为哪个是对象,哪个是对象的属性或者它指的是哪个对象。
任何直观有意义的对象都应该适合作为元素。它的属性(或属性)将是xml中具有属性的子元素中的这些元素的属性。
我认为对于简单的情况,例如在示例中,对象取向类比工作可以确定哪个是元素,哪个是元素的属性。
答案 14 :(得分:4)
存储对象属性的两种方法都是完全有效的。你应该背离务实的考虑。尝试回答以下问题:
可读性是否重要?
...
答案 15 :(得分:2)
对一些不良信息进行一些修正:
@John Ballinger:Attributies可以包含任何角色数据。 &LT; &GT; &安培; “'需要分别转义到&amp; lt;&amp; gt;&amp; amp;&amp; quot;和&amp; quot;如果您使用XML库,它将为您处理。
地狱,一个属性可以包含二进制数据,如图像,如果你真的想要,只需通过base64编码并使其成为数据:URL。
@feenster:在IDS或NAMES的情况下,属性可以包含以空格分隔的多个项目,其中包括数字。 Nitpicky,但这最终可以节省空间。
使用属性可以使XML与JSON保持竞争力。请参阅 Fat Markup: Trimming the Fat Markup Myth one calorie at a time 。
答案 16 :(得分:1)
我总是对这些讨论的结果感到惊讶。对我来说,有一个非常简单的规则来决定数据是属于属性还是属于内容,而且数据是否具有可导航的子结构。
因此,例如,非标记文本始终属于属性。总是
列表属于子结构或内容。随着时间推移包括嵌入的结构化子内容的文本属于内容。 (根据我的经验,当使用XML进行数据存储或交换时,相对较少 - 带有标记的文本。)
以这种方式编写的XML模式很简洁。
每当我看到像<car><make>Ford</make><color>Red</color></car>
这样的案例时,我就会对自己说“gee,作者是否认为make元素中会有子元素?” <car make="Ford" color="Red" />
明显更具可读性,毫无疑问如何处理空白等。
只考虑空白处理规则,我相信这是XML设计者的明确意图。
答案 17 :(得分:0)
在HTML中非常清楚,可以清楚地看到属性和标记的差异:
如果你只是将纯数据作为XML,那么差异就不那么明显了。数据可以位于标记之间或作为属性。
=&GT;大多数数据应该在标记之间。
如果你想在这里使用属性:你可以将数据分成两类:数据和“元数据”,其中元数据不是你要呈现的记录的一部分,但是像“格式版本”,“创建日期“等等。
<customer format="">
<name></name>
...
</customer>
还可以说:“使用属性来表征标签,使用标签自己提供数据。”
答案 18 :(得分:-1)
我同意feenster。如果可以的话,远离属性。元素是进化友好的,并且在Web服务工具包之间更具互操作性。您永远不会发现这些工具包使用属性序列化您的请求/响应消息。这也很有意义,因为我们的消息是Web服务工具包的数据(而不是元数据)。
答案 19 :(得分:-1)
随着时间的推移,属性很容易变得难以管理。我个人总是远离他们。解析器和用户都更加明确,可读/可用元素。
只有我曾经使用它们的时间是定义资产网址的文件扩展名:
<image type="gif">wank.jpg</image> ...etc etc
我想如果你知道100%属性不需要扩展你可以使用它们,但你知道多少次。
<image>
<url>wank.jpg</url>
<fileType>gif</fileType>
</image>