XML属性与XML元素
在工作中,我们被要求创建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文档的结构时应如何决定何时使用属性或者元素?
解决方案
回答
两种存储对象属性的方法都是完全有效的。我们应该脱离务实的考虑。尝试回答以下问题:
- 哪种表示方式可以更快地进行数据解析\生成?
- 哪种表示方式可以加快数据传输速度?
- 可读性重要吗? ...
回答
百万美元的问题!
首先,现在不必太担心性能。我们会惊讶于优化的xml解析器将如何快速地遍历xml。更重要的是,我们未来的设计是什么:随着XML的发展,我们将如何保持松散的耦合和互操作性?
更具体地讲,可以使元素的内容模型更复杂,但是很难扩展属性。
回答
两种方法都可以争论,但是同事是对的,因为应该将XML用于实际数据周围的"标记"或者元数据。就我们而言,这是正确的,因为在使用XML对域建模时,有时很难确定元数据和数据之间的界线。在实践中,我假装标记中的任何内容都是隐藏的,并且仅可读标记外的数据。这样的文件有意义吗?
众所周知,XML很庞大。对于运输和存储,如果我们有足够的处理能力,则强烈建议进行压缩。由于XML的重复性,它可以很好地压缩,有时效果非常好。我的大文件压缩到其原始大小的不到5%。
支持我们立场的另一点是,当另一个团队在讨论样式时(大多数XML工具将像处理所有#PCDATA文档一样容易处理所有属性的文档),我们在争论实用性。虽然不能完全忽略样式,但技术优点应更加重要。
回答
如有疑问,当我们没有明确的理由使用属性时,KISS-为什么混合使用属性和元素。如果我们以后决定定义XSD,那么最终也将变得更加干净。然后,如果我们甚至以后决定从XSD生成类结构,那也将更加简单。
回答
我使用以下经验法则:
- 属性是自包含的,即颜色,ID,名称。
- 元素是具有或者可能具有其自己的属性或者包含其他元素的东西。
所以你的亲近了。我会做类似的事情:
编辑:根据以下反馈更新了原始示例。
<ITEM serialNumber="something"> <BARCODE encoding="Code39">something</BARCODE> <LOCATION>XYX</LOCATION> <TYPE modelNumber="something"> <VENDOR>YYZ</VENDOR> </TYPE> </ITEM>
回答
这很大程度上是一个偏好问题。我尽可能使用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>
回答
这可能取决于用法。用于表示从数据库生成的结构化数据的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而又不会破坏使用它的现有代码时,IMO XML才是最有用的。
回答
属性存在的一些问题是:
- 属性不能包含多个值(子元素可以)
- 属性不容易扩展(用于将来的更改)
- 属性不能描述结构(子元素可以)
- 程序代码更难以操纵属性
- 属性值不容易针对DTD进行测试
如果将属性用作数据的容器,则最终会导致难以阅读和维护的文档。尝试使用元素来描述数据。仅使用属性来提供与数据无关的信息。
不要这样结束(这不是应该使用XML的方式):
<note day="12" month="11" year="2002" to="Tove" to2="John" from="Jani" heading="Reminder" body="Don't forget me this weekend!"> </note>
资料来源:http://www.w3schools.com/xml/xml_dtd_el_vs_attr.asp
回答
将元素用于数据,将属性用于元数据(有关元素数据的数据)。
地狱,如果我们确实需要的话,一个属性可以包含二进制数据,例如图像,只需对其进行base64编码并将其设置为数据:URL。
@feenster:对于IDS或者NAMES,属性可以包含以空格分隔的多个项目,其中包括数字。有点挑剔,但这最终可以节省空间。
回答
使用属性可以使XML与JSON保持竞争力。请参阅脂肪加价:修剪脂肪加价神话一次只能消耗一个卡路里。
回答
其他人介绍了如何区分元素的属性,但从更一般的角度讲,将所有内容都放入属性中,因为这会使生成的XML更小,这是错误的。
XML并不是为了紧凑而设计的,而是要具有可移植性和可读性。如果我们想减小传输中数据的大小,请使用其他工具(例如Google的协议缓冲区)。
<foo title="bar"/>;
" XML"代表"可扩展标记语言"。标记语言表示数据是文本,并用有关结构或者格式的元数据标记。
<foo> <title>bar</title>; </foo>;
XHTML是按预期方式使用XML的示例:
在这里,元素和属性之间的区别很明显。文本元素显示在浏览器中,属性是有关如何显示它们的说明(尽管有一些标记不能以这种方式工作)。
当XML不是用作标记语言,而是用作数据序列化语言时,会出现混乱,在这种语言中,"数据"和"元数据"之间的区别更加模糊。因此,除了不能用属性表示的事物外,元素和属性之间的选择几乎是任意的(请参见fennster的答案)。
回答
关于属性与元素,我在架构设计中使用以下准则:
属性的首选项是它提供了以下内容:
我在技术上可行的情况下添加了代码,因为有时无法使用属性。例如,属性集选择。例如,当前模式语言无法使用(startDate和endDate)xor(startTS和endTS)
如果XML模式开始允许"全部"内容模型受到限制或者扩展,那么我可能会删除它
{段落}
回答
{段落}
{段落}
回答
{段落}
{段落}
<p><span lang="es">El Jefe</span> insists that you <em class="urgent">MUST</em> complete your project by Friday.</p>
{段落}
{段落}
回答
{段落}
- 将元素用于长时间运行的文本(通常是字符串或者normalizedString类型的元素)
- 如果一个元素有两个值的分组(例如eventStartDate和eventEndDate),请不要使用属性。在前面的示例中,应该为"事件"添加一个新元素,其中可能包含startDate和endDate属性。
- 业务日期,日期时间和数字(例如计数,金额和费率)应为元素。
- 非业务时间元素(例如上一次更新,过期)应该是属性。
- 非业务数字(例如哈希码和索引)应该是属性。*如果类型复杂,请使用元素。
- 如果值是简单类型且不重复,则使用属性。
- xml:id和xml:lang必须是引用XML模式的属性
- 在技术上可行时,请优先选择属性。
{段落}
- 唯一的(属性不能多次出现)
- 顺序没关系
- 上面的属性是可继承的(这是当前模式语言不支持"全部"内容模型的东西)
- 好处是它们不那么冗长,占用的带宽也较少,但这并不是选择属性而不是元素的真正原因。
{段落}
{段落}