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>

其他回答

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

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

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

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

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

这很大程度上是个人偏好的问题。在可能的情况下,我使用元素进行分组,并使用属性进行数据,因为我认为这比替代方法更紧凑。

例如,我更喜欢.....

<?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模式非常简洁。

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

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

我同意芬斯特的观点。如果可以的话,远离属性。元素是进化友好的,并且在web服务工具包之间具有更强的互操作性。您永远不会发现这些工具包使用属性序列化您的请求/响应消息。这也是有意义的,因为我们的消息是web服务工具包的数据(而不是元数据)。

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

Use elements for long running text (usually those of string or normalizedString types) Do not use an attribute if there is grouping of two values (e.g. eventStartDate and eventEndDate) for an element. In the previous example, there should be a new element for "event" which may contain the startDate and endDate attributes. Business Date, DateTime and numbers (e.g. counts, amount and rate) should be elements. Non-business time elements such as last updated, expires on should be attributes. Non-business numbers such as hash codes and indices should be attributes.* Use elements if the type will be complex. Use attributes if the value is a simple type and does not repeat. xml:id and xml:lang must be attributes referencing the XML schema Prefer attributes when technically possible.

属性的优先级是它提供了以下内容:

唯一的(该属性不能出现多次) 顺序不重要 上面的属性是可继承的(这是“所有”内容模型在当前模式语言中不支持的) 额外的好处是它们不那么冗长,占用的带宽也更少,但这并不是更喜欢属性而不是元素的真正原因。

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

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