2024-09-15 07:00:01

XML属性vs 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文档的结构时,如何决定何时使用属性或元素?


当前回答

随着时间的推移,属性很容易变得难以管理,相信我。我个人总是远离他们。元素对于解析器和用户来说更加显式和可读/可用。

我唯一一次使用它们是定义资产url的文件扩展名:

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

我想如果你100%知道属性不需要扩展,你就可以使用它们,但你知道多少次。

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

其他回答

这两种方式都有争议,但您的同事认为XML应该用于“标记”或围绕实际数据的元数据,这一点是正确的。对您来说,在用XML建模域时,有时很难确定元数据和数据之间的界限。实际上,我所做的是假装标记中的任何内容都是隐藏的,只有标记之外的数据是可读的。这份文件在这方面有意义吗?

XML是出了名的庞大。对于运输和存储,如果你能负担得起处理能力,强烈建议压缩。XML压缩得很好,有时压缩得非常好,因为它具有重复性。我曾经把大文件压缩到不到原始大小的5%。

支持您立场的另一点是,当其他团队在争论样式时(大多数XML工具处理全属性文档就像处理全#PCDATA文档一样容易),您在争论实用性。虽然不能完全忽视风格,但技术优点应该更重要。

这是个价值百万美元的问题!

首先,现在不要太担心性能。您会惊讶于优化的XML解析器解析XML的速度有多快。更重要的是,您对未来的设计是什么:随着XML的发展,您将如何保持松耦合和互操作性?

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

这个问题没有统一的答案(我曾大量参与W3C规范的创建)。XML可以用于许多目的——类似文本的文档、数据和声明性代码是其中最常见的三种。我也经常把它用作数据模型。在这些应用程序的某些方面,属性更常见,而在其他方面,子元素更自然。各种工具的特性也使它们的使用变得更容易或更困难。

XHTML is one area where attributes have a natural use (e.g. in class='foo'). Attributes have no order and this may make it easier for some people to develop tools. OTOH attributes are harder to type without a schema. I also find namespaced attributes (foo:bar="zork") are often harder to manage in various toolsets. But have a look at some of the W3C languages to see the mixture that is common. SVG, XSLT, XSD, MathML are some examples of well-known languages and all have a rich supply of attributes and elements. Some languages even allow more-than-one-way to do it, e.g.

<foo title="bar"/>;

or

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

注意,它们在语法上是不等价的,需要处理工具的显式支持)

我的建议是,查看与您的应用程序最接近的领域的常见实践,并考虑您可能希望应用什么工具集。

最后,确保将名称空间与属性区分开来。一些XML系统(例如Linq)在API中将名称空间表示为属性。在我看来,这很丑陋,而且可能令人困惑。

我总是对这类讨论的结果感到惊讶。对我来说,有一个非常简单的规则来决定数据是否属于属性或内容,即数据是否具有可导航的子结构。

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

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

以这种方式编写的XML模式非常简洁。

每当我看到像<car><make>Ford</make><color>Red</color></car>这样的情况时,我就会想“咦,作者认为make元素中会有子元素吗?”<car make="Ford" color="Red" />可读性明显更好,关于如何处理空白等问题毫无疑问。

考虑到空格处理规则,我相信这是XML设计者的明确意图。

只是对一些不好的信息做一些更正:

属性可以包含任何字符数据。< > & " '需要转义到&lt;&gt;,“;事情就让它,,,分别。如果您使用XML库,它将为您处理这些问题。

一个属性可以包含二进制数据,如图像,如果你真的需要,只需通过base64编码并将其设置为data: URL。

@feenster:在IDS或NAMES的情况下,属性可以包含空格分隔的多个项,其中包括数字。吹毛求疵,但这最终可以节省空间。

使用属性可以保持XML与JSON的竞争力。参见脂肪加价:每次减少一卡路里的脂肪加价神话。