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


当前回答

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

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

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

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

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

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

其他回答

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

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

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

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

如何利用我们来之不易的面向对象的直觉?我通常发现,思考哪个是对象,哪个是对象的属性,或者它指的是哪个对象是很直接的。

任何直观上作为对象有意义的东西都应该作为元素。它的属性(或属性)将是xml中这些元素的属性或带有attribute的子元素。

我认为对于更简单的情况,比如在例子中,面向对象的类比可以很好地找出哪个是元素,哪个是元素的属性。

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

我唯一一次使用它们是定义资产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>