XML属性与XML元素

时间:2008-08-29 01:15:52

标签: xml xsd

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

20 个答案:

答案 0 :(得分:135)

我使用这个经验法则:

  1. 属性是自包含的,即颜色,ID,名称。
  2. 元素具有或可能具有自己的属性或包含其他元素。
  3. 所以你的很近。我会做的事情如下:

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

      <ITEM serialNumber="something">
          <BARCODE encoding="Code39">something</BARCODE>
          <LOCATION>XYX</LOCATION>
          <TYPE modelNumber="something">
             <VENDOR>YYZ</VENDOR>
          </TYPE>
       </ITEM>
    

答案 1 :(得分:45)

属性的一些问题是:

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

答案 2 :(得分:36)

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

答案 3 :(得分:30)

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>

答案 4 :(得分:22)

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

答案 5 :(得分:9)

我在架构设计中使用以下关于属性与元素的指南:

  • 将元素用于长时间运行的文本(通常是字符串或 normalizedString types)
  • 如果存在两个值的分组,则不要使用属性(例如 eventStartDate和eventEndDate)用于元素。在前面的例子中, 应该有一个“event”的新元素,它可能包含startDate和 endDate属性。
  • 营业日期,日期时间和数字(例如计数,金额和费率)应该是 元件。
  • 非营业时间元素,例如上次更新,过期应该是 属性。
  • 哈希代码和索引等非商业号码应该是属性。*如果类型复杂,请使用元素。
  • 如果值是简单类型且不重复,请使用属性。
  • xml:id和xml:lang必须是引用XML架构的属性
  • 在技术上可行时首选属性。

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

  • 唯一(属性不能多次出现)
  • 顺序无所谓
  • 以上属性是可继承的(这是“所有”内容模型在当前模式语言中不支持的内容)
  • 奖励是它们不那么冗长,占用的带宽更少,但这并不是优先考虑属性而非元素的理由。

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

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

答案 6 :(得分: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中的属性。国际海事组织这是丑陋的,可能令人困惑。

答案 7 :(得分:7)

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

答案 8 :(得分:5)

百万美元的问题!

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

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

答案 9 :(得分:5)

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

XML不是设计得紧凑,而是可移植和人类可读。如果您想减少传输中的数据大小,请使用其他内容(例如google's protocol buffers)。

答案 10 :(得分:5)

使用元素数据和元数据元素(有关元素数据的数据)。

如果元素在选择字符串中显示为谓词,则表明它应该是一个属性。同样,如果一个属性永远不会被用作谓词,那么它可能不是有用的元数据。

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

答案 11 :(得分:4)

这在很大程度上取决于偏好。我尽可能使用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>

答案 12 :(得分:4)

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

XML非常笨重。对于运输和存储,如果您能够负担得起处理能力,强烈建议使用压缩。由于其重复性,XML压缩得很好,有时非常好。我的大文件压缩到原始大小的5%以下。

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

答案 13 :(得分:4)

如何充分利用我们辛苦挣来的面向对象的直觉?我通常发现很容易认为哪个是对象,哪个是对象的属性或者它指的是哪个对象。

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

我认为对于简单的情况,例如在示例中,对象取向类比工作可以确定哪个是元素,哪个是元素的属性。

答案 14 :(得分:4)

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

  1. 哪种表示方式可以加快数据解析\生成?
  2. 哪种表示可以加快数据传输速度?
  3. 可读性是否重要?

    ...

答案 15 :(得分:2)

对一些不良信息进行一些修正:

@John Ballinger:Attributies可以包含任何角色数据。 &LT; &GT; &安培; “'需要分别转义到&amp; lt;&amp; gt;&amp; amp;&amp; quot;和&amp; quot;如果您使用XML库,它将为您处理。

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

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

使用属性可以使XML与JSON保持竞争力。请参阅 Fat Markup: Trimming the Fat Markup Myth one calorie at a time

答案 16 :(得分:1)

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

因此,例如,非标记文本始终属于属性。总是

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

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

每当我看到像<car><make>Ford</make><color>Red</color></car>这样的案例时,我就会对自己说“gee,作者是否认为make元素中会有子元素?” <car make="Ford" color="Red" />明显更具可读性,毫无疑问如何处理空白等。

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

答案 17 :(得分:0)

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

  1. 所有数据都在标记之间
  2. 属性用于表征此数据(例如格式)
  3. 如果你只是将纯数据作为XML,那么差异就不那么明显了。数据可以位于标记之间或作为属性。

    =&GT;大多数数据应该在标记之间。

    如果你想在这里使用属性:你可以将数据分成两类:数据和“元数据”,其中元数据不是你要呈现的记录的一部分,但是像“格式版本”,“创建日期“等等。

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

    还可以说:“使用属性来表征标签,使用标签自己提供数据。”

答案 18 :(得分:-1)

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

答案 19 :(得分:-1)

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

只有我曾经使用它们的时间是定义资产网址的文件扩展名:

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

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

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