XML属性与XML元素


253

在工作中,我们被要求创建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
我发现了这个非常好的资源:ibm.com/developerworks/xml/library/x-eleatt.html
Laurens Holst 2010年

5
+1 “......辩论是关于什么是真正的元数据。”
2013年

请连字符注小写的标签名称:stackoverflow.com/questions/1074447/...

Answers:


145

我使用以下经验法则:

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

所以你的亲近了。我会做类似的事情:

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

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

22
我通读了一些答案,但从我的经验来看,没有得到足够强调的是,如果您将数据归入“属性”并且突然出现一个>或<您,那么XML文档将中断,我认为有五个ascii字符(>, <,&,?,“)会杀死它。如果这个特殊字符在Element中,则可以在该数据周围添加一些CDATA标记。我想说的是,仅当您100%知道要放置什么值时才使用属性。在那里,例如,一个整数或日期,就会产生该电脑大概什么,如果条形码是由人产生那么它不应该是一个属性。
约翰·巴林杰

39
聚会真的很晚了,但是特殊的ASCII char参数是错误的-这就是属性和文本数据转义的目的。
米卡丹2009年

2
@donroby-对不起,那是我在交流中的错误。通过转义,我的意思是XML编码。'<'=&lt; 在我看来,根据构成内容的字符而不是内容的含义在属性或元素之间做出选择似乎很奇怪。
米卡丹(Michaelahtan)2010年

3
@donroby:不正确。的替换文本&lt;&#60;,是字符引用,不是实体引用。&lt;在属性上可以。请参阅:w3.org/TR/REC-xml/#sec-predefined-ent
发生

14
@John:如果这是一个问题,那么您的工具链中有些东西不能产生有效的XML。我认为这不是在属性或元素之间进行选择的原因。(此外,您不能在用户输入周围“仅添加CDATA标记”,因为它可能包含]]>!)
导致2010年

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


2
第一点是错误的,请参阅:w3.org/TR/xmlschema-2/#derivation-by-list
porges 2010年

6
我想说的第一点是正确的,并且list是解决此问题的部分解决方法。不能有多个具有相同名称的属性。With list属性仍然只有一个值,它是一些数据类型的用空格分隔的列表。分隔字符是固定的,因此如果所需数据类型的单个值可以包含空格,则不能有多个值。这排除了在一个“地址”属性中具有多个地址的机会。
jasso

7
“属性更难被程序代码操纵”-不能同意这一点。实际上,我发现相反的说法是正确的。真正说明这两种方式还不够。
Paul Alexander

4
我还要补充一点,使用XML-Schema,Schematron和Relax等,针对DTD的验证不再具有实际意义。等 所有这些都提供了更强大的功能,在某些情况下还提供了更直观的验证XML文档的方法。另外,W3Schools对于任何事情都是一个很差的参考

37

“ 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不是用作标记语言,而是用作数据序列化语言时,会出现混乱,在这种语言中,“数据”和“元数据”之间的区别更加模糊。因此,除了不能用属性表示的事物之外,元素和属性之间的选择几乎是任意的(请参见fennster的答案)。


32

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>

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而不破坏使用它的现有代码时,IMO XML最为有用。


关于“条形码”的要点,我急于举个例子,肯定会将其分解为自己的内容。在XSD / DTD上也很不错。
Chuck

10

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

  • 将元素用于长时间运行的文本(通常是字符串或normalizedString类型的元素)
  • 如果一个元素有两个值的组合(例如eventStartDate和eventEndDate),则不要使用属性。在前面的示例中,应该为“事件”添加一个新元素,其中可能包含startDate和endDate属性。
  • 业务日期,日期时间和数字(例如,计数,金额和费率)应为元素。
  • 非业务时间元素(例如上一次更新,过期)应该是属性。
  • 非业务数字(例如哈希码和索引)应为属性。*如果类型复杂,请使用元素。
  • 如果值是简单类型且不重复,则使用属性。
  • xml:id和xml:lang必须是引用XML模式的属性
  • 在技​​术上可行时,请优先选择属性。

属性的首选项是它提供以下内容:

  • 唯一的(属性不能多次出现)
  • 顺序没关系
  • 以上属性是可继承的(这是当前模式语言不支持“所有”内容模型的东西)
  • 好处是它们不那么冗长,占用的带宽也较少,但这并不是选择属性而不是元素的真正原因。

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

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


8

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


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中的属性。海事组织这是丑陋的,并且可能造成混乱。


6

其他人讨论了如何区分元素的属性,但从更一般的角度来看,将所有内容都放入属性中,因为这会使生成的XML变小是错误的。

XML并不是为了紧凑而设计的,而是要具有可移植性和可读性。如果您想减小传输中数据的大小,请使用其他工具(例如google的协议缓冲区)。


较小的XML文本更易于阅读,因为它更小!
纳什夫

5

百万美元的问题!

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

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


5

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

  1. 哪种表示方式可以更快地进行数据解析\生成?

  2. 哪种表示方式可以加快数据传输速度?

  3. 可读性重要吗?

    ...


5

将元素用于数据,将属性用于元数据(有关元素数据的数据)。

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

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


4

两种方法都可以争论,但是您的同事是对的,因为应该将XML用于实际数据周围的“标记”或元数据。就您而言,这是正确的,因为在使用XML对域建模时,有时很难确定元数据和数据之间的界线。在实践中,我所假装的是标记中的所有内容都是隐藏的,并且只有标记外部的数据才可读。这样的文件有意义吗?

众所周知,XML很庞大。对于运输和存储,如果您有足够的处理能力,则强烈建议压缩。由于XML的重复性,它的压缩效果很好,有时效果非常好。我将大文件压缩到其原始大小的不到5%。

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


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>

2
恐怕这完全是错误的-您应该遵循W3C准则:w3schools.com/DTD/dtd_el_vs_attr.asp-XML不应基于可读性或使其“紧凑”而形成-而是应为此目的正确使用元素或属性他们是专为。
维达尔

24
抱歉,这是误导。W3schools页面不是W3C guidleines。W3C XML建议(我曾参加过该建议)允许根据用户的需求和样式来使用元素和属性。
peter.murray.rust

4

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

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

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


2

对一些错误信息的一些更正:

@John Ballinger:属性可以包含任何字符数据。<>&“'需要分别转义为&lt;&amp;&quot;和&quot;。如果您使用XML库,它将为您处理。

地狱,如果您确实需要,一个属性可以包含二进制数据,例如图像,只需对它进行base64编码并将其设置为数据:URL。

@feenster:对于IDS或NAMES,属性可以包含以空格分隔的多个项目,其中包括数字。不错,但是最终可以节省空间。

使用属性可以使XML与JSON保持竞争力。请参阅脂肪加标:修正脂肪加标神话一次仅含一个卡路里


不只是ID或名称。它们可以包含以空格分隔的几乎所有列表。
约翰·桑德斯

@JohnSaunders IDS或NAMES是特定的DTD类型(我认为也是XML Schema),大多数XML处理器在较低级别上都支持它们。如果由应用程序层而不是XML库处理,则任何类型的字符数据都可以工作(分隔值或其他值)。
brianary

就个人而言,仅仅因为可以做并不意味着你应该做。
Lankymart

1
@Lankymart正如我所说,我只是在更正一些不正确的信息(由于某些原因得分很高)。二进制数据通常根本不属于XML。
2013年

1

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

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

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

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

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

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


我可以阅读的少数解释之一。不知道这是否是个好主意...但至少我明白这一点;)
Thufir

0

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

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

如果您仅将纯数据作为XML,那么区别就不那么明显了。数据可以位于标记之间或作为属性。

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

如果要在此处使用属性:可以将数据分为两类:数据和“元数据”,其中元数据不是记录的一部分,您想显示,但是诸如“格式版本”,“创建日期”之类的内容等

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

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


-1

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


-1

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

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

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

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

<image>
  <url>wank.jpg</url>
  <fileType>gif</fileType>
</image>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.