261

在工作中,我们被要求创建 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 文档的结构时,您应该如何决定何时使用属性或元素?

4

20 回答 20

149

我使用这个经验法则:

  1. 属性是自包含的东西,即颜色、ID、名称。
  2. 元素是具有或可能具有自己的属性或包含其他元素的东西。

所以你的很接近。我会做类似的事情:

编辑:根据下面的反馈更新了原始示例。

  <ITEM serialNumber="something">
      <BARCODE encoding="Code39">something</BARCODE>
      <LOCATION>XYX</LOCATION>
      <TYPE modelNumber="something">
         <VENDOR>YYZ</VENDOR>
      </TYPE>
   </ITEM>
于 2008-08-29T01:28:13.203 回答
48

属性的一些问题是:

  • 属性不能包含多个值(子元素可以)
  • 属性不易扩展(以备将来更改)
  • 属性不能描述结构(子元素可以)
  • 属性更难被程序代码操作
  • 属性值不容易针对 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

于 2009-01-07T12:49:45.860 回答
39

“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 不是用作标记语言,而是用作数据序列化语言时,就会出现混淆,其中“数据”和“元数据”之间的区别更加模糊。所以元素和属性之间的选择或多或少是任意的,除了不能用属性表示的东西(见芬斯特的回答)。

于 2010-06-24T04:02:05.380 回答
33

XML 元素与 XML 属性

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>
于 2014-04-17T12:56:33.113 回答
23

这可能取决于您的使用情况。用于表示从数据库生成的结构化数据的 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 在不破坏现有代码的情况下可以灵活使用时最有用。

于 2008-09-30T10:24:12.287 回答
10

关于属性与元素,我在架构设计中使用以下准则:

  • 对长时间运行的文本使用元素(通常是字符串或规范化字符串类型的元素)
  • 如果一个元素有两个值(例如 eventStartDate 和 eventEndDate)的分组,则不要使用属性。在前面的示例中,“event”应该有一个新元素,其中可能包含 startDate 和 endDate 属性。
  • 业务日期、日期时间和数字(例如计数、金额和比率)应该是元素。
  • 非业务时间元素,如 last updated、expires on 应该是属性。
  • 哈希码和索引等非业务数字应该是属性。* 如果类型很复杂,请使用元素。
  • 如果值是简单类型且不重复,则使用属性。
  • xml:id 和 xml:lang 必须是引用 XML 模式的属性
  • 在技​​术上可能的情况下首选属性。

属性的偏好是它提供以下内容:

  • 唯一(属性不能出现多次)
  • 顺序无所谓
  • 上述属性是可继承的(这是“所有”内容模型在当前模式语言中不支持的东西)
  • 好处是它们不那么冗长并且占用的带宽更少,但这并不是更喜欢属性而不是元素的真正理由。

在技术上可行时添加,因为有时无法使用属性。例如,属性集选择。例如使用 (startDate and endDate) xor (startTS and endTS) 在当前模式语言中是不可能的

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

于 2010-12-16T07:33:25.157 回答
9

如果有疑问,KISS——当你没有明确的理由使用属性时,为什么要混合属性和元素。如果您稍后决定定义 XSD,那最终也会变得更干净。然后,如果您以后决定从您的 XSD 生成一个类结构,那也会更简单。

于 2008-08-29T01:27:43.987 回答
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 中的属性。IMO 这很丑陋并且可能令人困惑。

于 2009-07-05T11:58:27.263 回答
6

其他人已经涵盖了如何区分属性和元素,但从更一般的角度来看,将所有内容都放在属性中,因为它会使生成的 XML 更小是错误的。

XML 的设计目的不是为了紧凑,而是为了便于携带和可读。如果您想减少传输中数据的大小,请使用其他东西(例如谷歌的协议缓冲区)。

于 2009-11-10T16:43:39.423 回答
5

这两种存储对象属性的方法都是完全有效的。你应该脱离务实的考虑。尝试回答以下问题:

  1. 哪种表示导致更快的数据解析\生成?

  2. 哪种表示会导致更快的数据传输?

  3. 可读性重要吗?

    ...

于 2008-08-29T01:23:23.857 回答
5

百万美元的问题!

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

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

于 2008-08-29T01:24:43.243 回答
5

对数据使用元素,对元数据使用属性(关于元素数据的数据)。

如果一个元素在您的选择字符串中显示为谓词,那么您有一个很好的迹象表明它应该是一个属性。同样,如果一个属性从不用作谓词,那么它可能不是有用的元数据。

请记住,XML 应该是机器可读的而不是人类可读的,并且对于大型文档,XML 压缩得非常好。

于 2009-01-15T19:22:35.370 回答
4

无论哪种方式都有争议,但您的同事在某种意义上是正确的,即 XML 应该用于“标记”或围绕实际数据的元数据。就您而言,您是对的,在用 XML 对您的域进行建模时,有时很难确定元数据和数据之间的界限在哪里。实际上,我所做的是假装标记中的任何内容都是隐藏的,只有标记之外的数据是可读的。以这种方式,该文件是否有意义?

XML 是出了名的笨重。对于传输和存储,如果您负担得起处理能力,强烈建议进行压缩。XML 压缩得很好,有时甚至非常好,因为它具有重复性。我已经将大文件压缩到其原始大小的 5% 以下。

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

于 2008-08-29T01:26:57.077 回答
4

这在很大程度上是一个偏好问题。我尽可能使用元素进行分组和数据属性,因为我认为这比替代方案更紧凑。

比如我更喜欢......

<?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>
于 2008-09-30T09:23:18.830 回答
4

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

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

我认为对于示例中的面向对象类比等更简单的情况,可以确定哪个是元素,哪个是元素的属性。

于 2011-02-09T13:08:51.930 回答
2

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

@John Ballinger:属性可以包含任何字符数据。< > & " ' 需要分别转义为 < > & " 和 ' 。如果您使用 XML 库,它会为您解决这个问题。

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

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

使用属性可以保持 XML 与 JSON 的竞争力。请参阅脂肪标记:一次修剪一卡路里的脂肪标记神话

于 2009-07-23T21:38:28.380 回答
1

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

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

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

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

每当我看到类似的情况<car><make>Ford</make><color>Red</color></car>时,我都会想“哎呀,作者是否认为 make 元素中会有子元素?” <car make="Ford" color="Red" />可读性更高,毫无疑问如何处理空格等。

仅给出空白处理规则,我相信这是 XML 设计者的明确意图。

于 2015-05-15T17:12:14.500 回答
0

这在 HTML 中非常清楚,可以清楚地看到属性和标记的差异:

  1. 所有数据都在标记之间
  2. 属性用于表征此数据(例如格式)

如果您只是将纯数据作为 XML,则存在不太明显的区别。数据可以位于标记之间或作为属性。

=> 大多数数据应该位于标记之间。

如果您想在这里使用属性:您可以将数据分为两类:数据和“元数据”,其中元数据不是您要呈现的记录的一部分,而是诸如“格式版本”、“创建日期”之类的内容, ETC。

<customer format="">
     <name></name>
     ...
</customer>

也可以说:“使用属性来表征标签,使用标签来提供数据本身。”

于 2011-08-31T02:44:50.353 回答
-1

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

于 2009-04-07T06:22:09.827 回答
-1

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

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

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

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

<image>
  <url>wank.jpg</url>
  <fileType>gif</fileType>
</image>
于 2011-04-08T19:51:46.277 回答